Commit ac1ded94b70a1a4f8c8a1d2c29a9b35e3fac0d8a

Authored by Andrii Shvaika
1 parent 1f8d790f

UUID refactoring

... ... @@ -20,12 +20,14 @@ import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity;
20 20 import org.thingsboard.server.dao.util.HsqlDao;
21 21 import org.thingsboard.server.dao.util.SqlDao;
22 22
  23 +import javax.persistence.Query;
  24 +
23 25 @SqlDao
24 26 @HsqlDao
25 27 @Repository
26 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 31 private static final String UNQ_KEY_CONFLICT_STATEMENT = "(component_descriptor.clazz=I.clazz)";
30 32
31 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 39 }
38 40
39 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 56 protected ComponentDescriptorEntity doProcessSaveOrUpdate(ComponentDescriptorEntity entity, String query) {
41 57 getQuery(entity, query).executeUpdate();
42 58 return entityManager.find(ComponentDescriptorEntity.class, entity.getUuid());
43 59 }
44 60
45 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 5 * you may not use this file except in compliance with the License.
6 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 10 * Unless required by applicable law or agreed to in writing, software
11 11 * distributed under the License is distributed on an "AS IS" BASIS,
... ...
... ... @@ -17,6 +17,8 @@ package org.thingsboard.server.dao.sql.query;
17 17
18 18 import lombok.extern.slf4j.Slf4j;
19 19 import org.apache.commons.lang3.StringUtils;
  20 +import org.springframework.beans.factory.annotation.Autowired;
  21 +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
20 22 import org.springframework.stereotype.Repository;
21 23 import org.thingsboard.server.common.data.EntityType;
22 24 import org.thingsboard.server.common.data.id.CustomerId;
... ... @@ -44,8 +46,6 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection;
44 46 import org.thingsboard.server.common.data.relation.EntityTypeFilter;
45 47 import org.thingsboard.server.dao.util.SqlDao;
46 48
47   -import javax.persistence.EntityManager;
48   -import javax.persistence.PersistenceContext;
49 49 import java.math.BigInteger;
50 50 import java.util.Collections;
51 51 import java.util.HashMap;
... ... @@ -75,7 +75,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
75 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 76 " SELECT from_id, from_type, to_id, to_type, relation_type, 1 as lvl" +
77 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 79 " UNION ALL" +
80 80 " SELECT r.from_id, r.from_type, r.to_id, r.to_type, r.relation_type, lvl + 1" +
81 81 " FROM relation r" +
... ... @@ -88,21 +88,23 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
88 88 public static final String HIERARCHICAL_TO_QUERY_TEMPLATE = HIERARCHICAL_QUERY_TEMPLATE.replace("$in", "to").replace("$out", "from");
89 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 94 @Override
95 95 public long countEntitiesByQuery(TenantId tenantId, CustomerId customerId, EntityCountQuery query) {
96 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 105 @Override
105 106 public PageData<EntityData> findEntityDataByQuery(TenantId tenantId, CustomerId customerId, EntityDataQuery query) {
  107 + EntityQueryContext ctx = new EntityQueryContext();
106 108 EntityType entityType = resolveEntityType(query.getEntityFilter());
107 109 EntityDataPageLink pageLink = query.getPageLink();
108 110
... ... @@ -126,9 +128,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
126 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 134 String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping);
133 135 String entityTypeStr;
134 136 if (query.getEntityFilter().getType().equals(EntityFilterType.RELATIONS_QUERY)) {
... ... @@ -137,9 +139,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
137 139 entityTypeStr = "'" + entityType.name() + "'";
138 140 }
139 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 143 } else {
142   - entityFieldsSelection = String.format("e.id, %s", entityTypeStr);
  144 + entityFieldsSelection = String.format("e.id id, %s entity_type", entityTypeStr);
143 145 }
144 146 String latestSelection = EntityKeyMapping.buildSelections(latestSelectionMapping);
145 147 String topSelection = "entities.*";
... ... @@ -150,13 +152,13 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
150 152 String fromClause = String.format("from (select %s from (select %s from %s e where %s) entities %s %s) result",
151 153 topSelection,
152 154 entityFieldsSelection,
153   - getEntityTableQuery(query.getEntityFilter(), entityType),
  155 + addEntityTableQuery(ctx, query.getEntityFilter(), entityType),
154 156 entityWhereClause,
155 157 latestJoins,
156 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 163 String dataQuery = String.format("select * %s", fromClause);
162 164
... ... @@ -177,17 +179,18 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
177 179 if (pageLink.getPageSize() > 0) {
178 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 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 188 CustomerId customerId,
186 189 EntityFilter entityFilter,
187 190 List<EntityKeyMapping> entityFieldsFilters,
188 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 194 String result = permissionQuery;
192 195 if (!entityFilterQuery.isEmpty()) {
193 196 result += " and " + entityFilterQuery;
... ... @@ -198,35 +201,42 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
198 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 205 switch (entityFilter.getType()) {
203 206 case RELATIONS_QUERY:
204 207 case DEVICE_SEARCH_QUERY:
205 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 212 default:
208 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 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 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 229 switch (entityFilter.getType()) {
220 230 case SINGLE_ENTITY:
221   - return this.singleEntityQuery((SingleEntityFilter) entityFilter);
  231 + return this.singleEntityQuery(ctx, (SingleEntityFilter) entityFilter);
222 232 case ENTITY_LIST:
223   - return this.entityListQuery((EntityListFilter) entityFilter);
  233 + return this.entityListQuery(ctx, (EntityListFilter) entityFilter);
224 234 case ENTITY_NAME:
225   - return this.entityNameQuery((EntityNameFilter) entityFilter);
  235 + return this.entityNameQuery(ctx, (EntityNameFilter) entityFilter);
226 236 case ASSET_TYPE:
227 237 case DEVICE_TYPE:
228 238 case ENTITY_VIEW_TYPE:
229   - return this.typeQuery(entityFilter);
  239 + return this.typeQuery(ctx, entityFilter);
230 240 case RELATIONS_QUERY:
231 241 case DEVICE_SEARCH_QUERY:
232 242 case ASSET_SEARCH_QUERY:
... ... @@ -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 250 switch (entityFilter.getType()) {
241 251 case RELATIONS_QUERY:
242   - return relationQuery((RelationsQueryFilter) entityFilter);
  252 + return relationQuery(ctx, (RelationsQueryFilter) entityFilter);
243 253 case DEVICE_SEARCH_QUERY:
244 254 DeviceSearchQueryFilter deviceQuery = (DeviceSearchQueryFilter) entityFilter;
245   - return entitySearchQuery(deviceQuery, EntityType.DEVICE, deviceQuery.getDeviceTypes());
  255 + return entitySearchQuery(ctx, deviceQuery, EntityType.DEVICE, deviceQuery.getDeviceTypes());
246 256 case ASSET_SEARCH_QUERY:
247 257 AssetSearchQueryFilter assetQuery = (AssetSearchQueryFilter) entityFilter;
248   - return entitySearchQuery(assetQuery, EntityType.ASSET, assetQuery.getAssetTypes());
  258 + return entitySearchQuery(ctx, assetQuery, EntityType.ASSET, assetQuery.getAssetTypes());
249 259 default:
250 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 265 EntityId rootId = entityFilter.getRootEntity();
256 266 //TODO: fetch last level only.
257 267 //TODO: fetch distinct records.
258 268 String lvlFilter = getLvlFilter(entityFilter.getMaxLevel());
259 269 String selectFields = "SELECT tenant_id, customer_id, id, type, name, label FROM " + entityType.name() + " WHERE id in ( SELECT entity_id";
260 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 274 String query = "( " + selectFields + from + ")";
266 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 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 284 return query;
271 285 }
272 286
273   - private String relationQuery(RelationsQueryFilter entityFilter) {
  287 + private String relationQuery(EntityQueryContext ctx, RelationsQueryFilter entityFilter) {
274 288 EntityId rootId = entityFilter.getRootEntity();
275 289 String lvlFilter = getLvlFilter(entityFilter.getMaxLevel());
276 290 String selectFields = getSelectTenantId() + ", " + getSelectCustomerId() + ", " +
277 291 " entity.entity_id as id," + getSelectType() + ", " + getSelectName() + ", " +
278 292 getSelectLabel() + ", entity.entity_type as entity_type";
279 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 297 StringBuilder whereFilter;
282 298 if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) {
283 299 whereFilter = new StringBuilder(" WHERE ");
284 300 boolean first = true;
285 301 boolean single = entityFilter.getFilters().size() == 1;
  302 + int entityTypeFilterIdx = 0;
286 303 for (EntityTypeFilter etf : entityFilter.getFilters()) {
287 304 if (first) {
288 305 first = false;
... ... @@ -290,21 +307,23 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
290 307 whereFilter.append(" AND ");
291 308 }
292 309 String relationType = etf.getRelationType();
293   - String entityTypes = etf.getEntityTypes().stream().map(type -> "'" + type + "'").collect(Collectors.joining(", "));
294 310 if (!single) {
295 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 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 316 if (!single) {
301 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 323 } else {
305 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 327 return "( " + selectFields + from + ")";
309 328 }
310 329
... ... @@ -410,10 +429,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
410 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 435 String query;
418 436 if (!StringUtils.isEmpty(latestFilters) && !StringUtils.isEmpty(textSearchQuery)) {
419 437 query = String.join(" AND ", latestFilters, textSearchQuery);
... ... @@ -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 451 if (!StringUtils.isEmpty(searchText) && !selectionMapping.isEmpty()) {
434 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 459 return String.format("(%s)", String.join(" or ", searchPredicates));
438 460 } else {
439 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 482 String type;
459 483 String name;
460 484 switch (filter.getType()) {
... ... @@ -473,7 +497,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
473 497 default:
474 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 505 private EntityType resolveEntityType(EntityFilter entityFilter) {
... ...
... ... @@ -37,31 +37,30 @@ public class EntityDataAdapter {
37 37
38 38 public static PageData<EntityData> createEntityData(EntityDataPageLink pageLink,
39 39 List<EntityKeyMapping> selectionMapping,
40   - List<Object[]> rows,
  40 + List<Map<String, Object>> rows,
41 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 43 int startIndex = pageLink.getPageSize() * pageLink.getPage();
44 44 boolean hasNext = pageLink.getPageSize() > 0 && totalElements > startIndex + rows.size();
45 45 List<EntityData> entitiesData = convertListToEntityData(rows, selectionMapping);
46 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 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 56 EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, id);
58 57 Map<EntityKeyType, Map<String, TsValue>> latest = new HashMap<>();
59 58 Map<String, TsValue[]> timeseries = new HashMap<>();
60 59 EntityData entityData = new EntityData(entityId, latest, timeseries);
61   - for (EntityKeyMapping mapping: selectionMapping) {
  60 + for (EntityKeyMapping mapping : selectionMapping) {
62 61 if (!mapping.isIgnore()) {
63 62 EntityKey entityKey = mapping.getEntityKey();
64   - Object value = row[mapping.getIndex()];
  63 + Object value = row.get(mapping.getValueAlias());
65 64 String strValue;
66 65 long ts;
67 66 if (entityKey.getType().equals(EntityKeyType.ENTITY_FIELD)) {
... ... @@ -69,7 +68,7 @@ public class EntityDataAdapter {
69 68 ts = System.currentTimeMillis();
70 69 } else {
71 70 strValue = convertValue(value);
72   - Object tsObject = row[mapping.getIndex() + 1];
  71 + Object tsObject = row.get(mapping.getTsAlias());
73 72 ts = tsObject != null ? Long.parseLong(tsObject.toString()) : 0;
74 73 }
75 74 TsValue tsValue = new TsValue(ts, strValue);
... ...
... ... @@ -72,6 +72,7 @@ public class EntityKeyMapping {
72 72 private boolean ignore = false;
73 73 private List<KeyFilter> keyFilters;
74 74 private EntityKey entityKey;
  75 + private int paramIdx = 0;
75 76
76 77 public boolean hasFilter() {
77 78 return keyFilters != null && !keyFilters.isEmpty();
... ... @@ -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 105 if (hasFilter()) {
105 106 String keyAlias = entityKey.getType().equals(EntityKeyType.ENTITY_FIELD) ? "e" : alias;
106 107 return keyFilters.stream().map(keyFilter ->
107   - this.buildKeyQuery(keyAlias, keyFilter));
  108 + this.buildKeyQuery(ctx, keyAlias, keyFilter));
108 109 } else {
109 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 115 String entityTypeStr;
115 116 if (entityFilter.getType().equals(EntityFilterType.RELATIONS_QUERY)) {
116 117 entityTypeStr = "entities.entity_type";
... ... @@ -118,12 +119,13 @@ public class EntityKeyMapping {
118 119 entityTypeStr = "'" + entityType.name() + "'";
119 120 }
120 121 String join = hasFilter() ? "left join" : "left outer join";
  122 + ctx.addStringParameter(alias + "_key_id", entityKey.getKey());
121 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 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 129 if (!entityKey.getType().equals(EntityKeyType.ATTRIBUTE)) {
128 130 String scope;
129 131 if (entityKey.getType().equals(EntityKeyType.CLIENT_ATTRIBUTE)) {
... ... @@ -144,13 +146,13 @@ public class EntityKeyMapping {
144 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 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 156 Collectors.joining(" AND "));
155 157 }
156 158
... ... @@ -262,33 +264,33 @@ public class EntityKeyMapping {
262 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 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 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 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 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 287 if (predicate.getType().equals(FilterPredicateType.NUMERIC)) {
286 288 if (key.getType().equals(EntityKeyType.ENTITY_FIELD)) {
287 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 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 294 return String.format("(%s or %s)", longQuery, doubleQuery);
293 295 }
294 296 } else {
... ... @@ -300,15 +302,16 @@ public class EntityKeyMapping {
300 302 }
301 303 String field = alias + "." + column;
302 304 if (predicate.getType().equals(FilterPredicateType.STRING)) {
303   - return this.buildStringPredicateQuery(field, (StringFilterPredicate) predicate);
  305 + return this.buildStringPredicateQuery(ctx, field, (StringFilterPredicate) predicate);
304 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 313 String operationField = field;
  314 + String paramName = getNextParameterName(field);
312 315 String value = stringFilterPredicate.getValue();
313 316 String stringOperationQuery = "";
314 317 if (stringFilterPredicate.isIgnoreCase()) {
... ... @@ -317,65 +320,77 @@ public class EntityKeyMapping {
317 320 }
318 321 switch (stringFilterPredicate.getOperation()) {
319 322 case EQUAL:
320   - stringOperationQuery = String.format("%s = '%s'", operationField, value);
  323 + stringOperationQuery = String.format("%s = :%s", operationField, paramName);
321 324 break;
322 325 case NOT_EQUAL:
323   - stringOperationQuery = String.format("%s != '%s'", operationField, value);
  326 + stringOperationQuery = String.format("%s != :%s", operationField, paramName);
324 327 break;
325 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 331 break;
328 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 335 break;
331 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 339 break;
334 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 343 break;
337 344 }
  345 + ctx.addStringParameter(paramName, value);
338 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 352 String numericOperationQuery = "";
344 353 switch (numericFilterPredicate.getOperation()) {
345 354 case EQUAL:
346   - numericOperationQuery = String.format("%s = %s", field, value);
  355 + numericOperationQuery = String.format("%s = :%s", field, paramName);
347 356 break;
348 357 case NOT_EQUAL:
349   - numericOperationQuery = String.format("%s != '%s'", field, value);
  358 + numericOperationQuery = String.format("%s != :%s", field, paramName);
350 359 break;
351 360 case GREATER:
352   - numericOperationQuery = String.format("%s > %s", field, value);
  361 + numericOperationQuery = String.format("%s > :%s", field, paramName);
353 362 break;
354 363 case GREATER_OR_EQUAL:
355   - numericOperationQuery = String.format("%s >= %s", field, value);
  364 + numericOperationQuery = String.format("%s >= :%s", field, paramName);
356 365 break;
357 366 case LESS:
358   - numericOperationQuery = String.format("%s < %s", field, value);
  367 + numericOperationQuery = String.format("%s < :%s", field, paramName);
359 368 break;
360 369 case LESS_OR_EQUAL:
361   - numericOperationQuery = String.format("%s <= %s", field, value);
  370 + numericOperationQuery = String.format("%s <= :%s", field, paramName);
362 371 break;
363 372 }
364 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 377 BooleanFilterPredicate booleanFilterPredicate) {
369   - boolean value = booleanFilterPredicate.isValue();
  378 + String paramName = getNextParameterName(field);
  379 + ctx.addBooleanParameter(paramName, booleanFilterPredicate.isValue());
370 380 String booleanOperationQuery = "";
371 381 switch (booleanFilterPredicate.getOperation()) {
372 382 case EQUAL:
373   - booleanOperationQuery = String.format("%s = %s", field, value);
  383 + booleanOperationQuery = String.format("%s = :%s", field, paramName);
374 384 break;
375 385 case NOT_EQUAL:
376   - booleanOperationQuery = String.format("%s != %s", field, value);
  386 + booleanOperationQuery = String.format("%s != :%s", field, paramName);
377 387 break;
378 388 }
379 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 24
25 25 @RunWith(ClasspathSuite.class)
26 26 @ClassnameFilters({
27   - "org.thingsboard.server.dao.service.sql.EntityServiceSqlTest"
  27 + "org.thingsboard.server.dao.service.sql.*SqlTest"
28 28 })
29 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 31 @ClassRule
42 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 38 "sql-test.properties"
49 39 );
50 40
51 41 // @ClassRule
52 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 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 54 // "sql/timescale/drop-all-tables.sql",
55 55 // "sql-test.properties"
... ...
... ... @@ -20,6 +20,7 @@ import com.google.common.util.concurrent.ListenableFuture;
20 20 import org.junit.After;
21 21 import org.junit.Assert;
22 22 import org.junit.Before;
  23 +import org.junit.Ignore;
23 24 import org.junit.Test;
24 25 import org.springframework.beans.factory.annotation.Autowired;
25 26 import org.thingsboard.server.common.data.DataConstants;
... ...
... ... @@ -3,18 +3,18 @@ database.ts.type=sql
3 3 sql.ts_inserts_executor_type=fixed
4 4 sql.ts_inserts_fixed_thread_pool_size=200
5 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 19 service.type=monolith
20 20
... ... @@ -26,16 +26,16 @@ service.type=monolith
26 26 #sql.ts_inserts_fixed_thread_pool_size=200
27 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 40 queue.core.pack-processing-timeout=3000
41 41 queue.rule-engine.pack-processing-timeout=3000
... ...