thingsboard-memoizeit
Changes
dao/src/main/resources/postgres/schema.sql 50(+38 -12)
Details
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/TsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/TsKvQuery.java
index 8d60f52..8ede698 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/TsKvQuery.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/TsKvQuery.java
@@ -15,8 +15,6 @@
*/
package org.thingsboard.server.common.data.kv;
-import java.util.Optional;
-
public interface TsKvQuery {
String getKey();
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java
index 2ea58af..dd3f283 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java
@@ -16,6 +16,8 @@
package org.thingsboard.server.dao.model.sql;
import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
import org.thingsboard.server.common.data.kv.*;
import org.thingsboard.server.dao.model.ToData;
@@ -29,6 +31,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.*;
@Entity
@Table(name = "attribute_kv")
@IdClass(AttributeKvCompositeKey.class)
+@EqualsAndHashCode
+@ToString
public class AttributeKvEntity implements ToData<AttributeKvEntry>, Serializable {
@Id
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java
index 3e13ff5..f08f873 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java
@@ -17,15 +17,23 @@ package org.thingsboard.server.dao.model.sql;
import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
import org.thingsboard.server.common.data.relation.EntityRelation;
+import javax.persistence.Transient;
import java.io.Serializable;
import java.util.UUID;
@AllArgsConstructor
@Data
+@EqualsAndHashCode
+@ToString
public class RelationCompositeKey implements Serializable {
+ @Transient
+ private static final long serialVersionUID = -4089175869616037592L;
+
private UUID fromId;
private String fromType;
private UUID toId;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java
index 1b15aa1..f8aa72c 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java
@@ -17,6 +17,8 @@ package org.thingsboard.server.dao.model.sql;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
import org.hibernate.annotations.Type;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.relation.EntityRelation;
@@ -32,11 +34,10 @@ import static org.thingsboard.server.dao.model.ModelConstants.*;
@Entity
@Table(name = RELATION_COLUMN_FAMILY_NAME)
@IdClass(RelationCompositeKey.class)
+@EqualsAndHashCode
+@ToString
public final class RelationEntity implements ToData<EntityRelation> {
- @Transient
- private static final long serialVersionUID = -4089175869616037592L;
-
@Id
@Column(name = RELATION_FROM_ID_PROPERTY)
private UUID fromId;
@@ -84,88 +85,6 @@ public final class RelationEntity implements ToData<EntityRelation> {
}
@Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode());
- result = prime * result + ((toId == null) ? 0 : toId.hashCode());
- result = prime * result + ((toType == null) ? 0 : toType.hashCode());
- result = prime * result + ((fromId == null) ? 0 : fromId.hashCode());
- result = prime * result + ((fromType == null) ? 0 : fromType.hashCode());
- result = prime * result + ((relationType == null) ? 0 : relationType.hashCode());
- result = prime * result + ((relationTypeGroup == null) ? 0 : relationTypeGroup.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- RelationEntity other = (RelationEntity) obj;
- if (additionalInfo == null) {
- if (other.additionalInfo != null)
- return false;
- } else if (!additionalInfo.equals(other.additionalInfo))
- return false;
- if (toId == null) {
- if (other.toId != null)
- return false;
- } else if (!toId.equals(other.toId))
- return false;
- if (fromId == null) {
- if (other.fromId != null)
- return false;
- } else if (!fromId.equals(other.fromId))
- return false;
- if (toType == null) {
- if (other.toType != null)
- return false;
- } else if (!toType.equals(other.toType))
- return false;
- if (fromType == null) {
- if (other.fromType != null)
- return false;
- } else if (!fromType.equals(other.fromType))
- return false;
- if (relationType == null) {
- if (other.relationType != null)
- return false;
- } else if (!relationType.equals(other.relationType))
- return false;
- if (relationTypeGroup == null) {
- if (other.relationTypeGroup != null)
- return false;
- } else if (!relationTypeGroup.equals(other.relationTypeGroup))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("AssetEntity [toId=");
- builder.append(toId);
- builder.append(", toType=");
- builder.append(toType);
- builder.append(", fromId=");
- builder.append(fromId);
- builder.append(", fromType=");
- builder.append(fromType);
- builder.append(", relationType=");
- builder.append(relationType);
- builder.append(", relationTypeGroup=");
- builder.append(relationTypeGroup);
- builder.append(", additionalInfo=");
- builder.append(additionalInfo);
- builder.append("]");
- return builder.toString();
- }
-
- @Override
public EntityRelation toData() {
EntityRelation relation = new EntityRelation();
if (toId != null && toType != null) {
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvCompositeKey.java
new file mode 100644
index 0000000..037c2df
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvCompositeKey.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.model.sql;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.persistence.Transient;
+import java.io.Serializable;
+import java.util.UUID;
+
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode
+@ToString
+public class TsKvCompositeKey implements Serializable{
+
+ @Transient
+ private static final long serialVersionUID = -4089175869616037523L;
+
+ private String entityType;
+ private UUID entityId;
+ private String key;
+ private long ts;
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvEntity.java
new file mode 100644
index 0000000..7d6901d
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvEntity.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.model.sql;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.thingsboard.server.common.data.kv.TsKvEntry;
+import org.thingsboard.server.dao.model.ToData;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+import static org.thingsboard.server.dao.model.ModelConstants.*;
+
+@Data
+@Entity
+@Table(name = "ts_kv")
+@IdClass(TsKvCompositeKey.class)
+@EqualsAndHashCode
+@ToString
+public final class TsKvEntity implements ToData<TsKvEntry> {
+
+ @Id
+ @Column(name = ENTITY_TYPE_COLUMN)
+ private String entityType;
+
+ @Id
+ @Column(name = ENTITY_ID_COLUMN)
+ private UUID entityId;
+
+ @Id
+ @Column(name = KEY_COLUMN)
+ private String key;
+
+ @Id
+ @Column(name = TS_COLUMN)
+ private long ts;
+
+ @Column(name = BOOLEAN_VALUE_COLUMN)
+ private Boolean booleanValue;
+
+ @Column(name = STRING_VALUE_COLUMN)
+ private String strValue;
+
+ @Column(name = LONG_VALUE_COLUMN)
+ private Long longValue;
+
+ @Column(name = DOUBLE_VALUE_COLUMN)
+ private Double doubleValue;
+
+ @Override
+ public TsKvEntry toData() {
+ return null;
+ }
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvLatestCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvLatestCompositeKey.java
new file mode 100644
index 0000000..a68ddf7
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvLatestCompositeKey.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.model.sql;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.persistence.Transient;
+import java.io.Serializable;
+import java.util.UUID;
+
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode
+@ToString
+public class TsKvLatestCompositeKey implements Serializable{
+
+ @Transient
+ private static final long serialVersionUID = -4089175869616037523L;
+
+ private String entityType;
+ private UUID entityId;
+ private String key;
+}
\ No newline at end of file
diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvLatestEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvLatestEntity.java
new file mode 100644
index 0000000..803b89a
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TsKvLatestEntity.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.model.sql;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.thingsboard.server.common.data.kv.TsKvEntry;
+import org.thingsboard.server.dao.model.ToData;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+import static org.thingsboard.server.dao.model.ModelConstants.*;
+
+@Data
+@Entity
+@Table(name = "ts_kv_latest")
+@IdClass(TsKvLatestCompositeKey.class)
+@EqualsAndHashCode
+@ToString
+public final class TsKvLatestEntity implements ToData<TsKvEntry> {
+
+ @Id
+ @Column(name = ENTITY_TYPE_COLUMN)
+ private String entityType;
+
+ @Id
+ @Column(name = ENTITY_ID_COLUMN)
+ private UUID entityId;
+
+ @Id
+ @Column(name = KEY_COLUMN)
+ private String key;
+
+ @Column(name = TS_COLUMN)
+ private long ts;
+
+ @Column(name = BOOLEAN_VALUE_COLUMN)
+ private Boolean booleanValue;
+
+ @Column(name = STRING_VALUE_COLUMN)
+ private String strValue;
+
+ @Column(name = LONG_VALUE_COLUMN)
+ private Long longValue;
+
+ @Column(name = DOUBLE_VALUE_COLUMN)
+ private Double doubleValue;
+
+ @Override
+ public TsKvEntry toData() {
+ return null;
+ }
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java
index 9e53cc6..f3371f2 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java
@@ -15,13 +15,20 @@
*/
package org.thingsboard.server.dao.sql.timeseries;
+import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.kv.TsKvQuery;
+import org.thingsboard.server.dao.DaoUtil;
+import org.thingsboard.server.dao.model.sql.TsKvEntity;
+import org.thingsboard.server.dao.model.sql.TsKvLatestCompositeKey;
+import org.thingsboard.server.dao.model.sql.TsKvLatestEntity;
+import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService;
import org.thingsboard.server.dao.timeseries.TimeseriesDao;
import java.util.List;
@@ -29,41 +36,80 @@ import java.util.List;
@Component
@Slf4j
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true")
-public class JpaTimeseriesDao implements TimeseriesDao {
+public class JpaTimeseriesDao extends JpaAbstractDaoListeningExecutorService implements TimeseriesDao {
- @Override
- public long toPartitionTs(long ts) {
- return 0;
- }
+ @Autowired
+ private TsKvRepository tsKvRepository;
+
+ @Autowired
+ private TsKvLatestRepository tsKvLatestRepository;
@Override
public ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, List<TsKvQuery> queries) {
+ return null;
+ }
+
+ private ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, TsKvQuery query) {
return null;
}
@Override
public ListenableFuture<TsKvEntry> findLatest(EntityId entityId, String key) {
- return null;
+ TsKvLatestCompositeKey compositeKey =
+ new TsKvLatestCompositeKey(
+ entityId.getEntityType().name(),
+ entityId.getId(),
+ key);
+ return service.submit(() ->
+ DaoUtil.getData(tsKvLatestRepository.findOne(compositeKey)));
}
@Override
public ListenableFuture<List<TsKvEntry>> findAllLatest(EntityId entityId) {
- return null;
+ return service.submit(() ->
+ DaoUtil.convertDataList(Lists.newArrayList(
+ tsKvLatestRepository.findAllByEntityTypeAndEntityId(
+ entityId.getEntityType().name(),
+ entityId.getId()))));
}
@Override
- public ListenableFuture<Void> save(EntityId entityId, long partition, TsKvEntry tsKvEntry, long ttl) {
- return null;
+ public ListenableFuture<Void> save(EntityId entityId, TsKvEntry tsKvEntry, long ttl) {
+ TsKvEntity entity = new TsKvEntity();
+ entity.setEntityType(entityId.getEntityType().name());
+ entity.setEntityId(entityId.getId());
+ entity.setTs(tsKvEntry.getTs());
+ entity.setKey(tsKvEntry.getKey());
+ entity.setStrValue(tsKvEntry.getStrValue().orElse(null));
+ entity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
+ entity.setLongValue(tsKvEntry.getLongValue().orElse(null));
+ entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
+ return service.submit(() -> {
+ tsKvRepository.save(entity);
+ return null;
+ });
}
@Override
- public ListenableFuture<Void> savePartition(EntityId entityId, long partition, String key, long ttl) {
+ public ListenableFuture<Void> savePartition(EntityId entityId, long tsKvEntryTs, String key, long ttl) {
return null;
}
@Override
public ListenableFuture<Void> saveLatest(EntityId entityId, TsKvEntry tsKvEntry) {
- return null;
+ TsKvLatestEntity latestEntity = new TsKvLatestEntity();
+ latestEntity.setEntityType(entityId.getEntityType().name());
+ latestEntity.setEntityId(entityId.getId());
+ latestEntity.setTs(tsKvEntry.getTs());
+ latestEntity.setKey(tsKvEntry.getKey());
+ latestEntity.setStrValue(tsKvEntry.getStrValue().orElse(null));
+ latestEntity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
+ latestEntity.setLongValue(tsKvEntry.getLongValue().orElse(null));
+ latestEntity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
+ return service.submit(() -> {
+ tsKvLatestRepository.save(latestEntity);
+ return null;
+ });
}
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/TsKvLatestRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/TsKvLatestRepository.java
new file mode 100644
index 0000000..8630649
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/TsKvLatestRepository.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.sql.timeseries;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.repository.CrudRepository;
+import org.thingsboard.server.dao.model.sql.TsKvLatestCompositeKey;
+import org.thingsboard.server.dao.model.sql.TsKvLatestEntity;
+
+import java.util.List;
+import java.util.UUID;
+
+@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true")
+public interface TsKvLatestRepository extends CrudRepository<TsKvLatestEntity, TsKvLatestCompositeKey> {
+
+ List<TsKvLatestEntity> findAllByEntityTypeAndEntityId(String entityType, UUID entityId);
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/TsKvRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/TsKvRepository.java
new file mode 100644
index 0000000..6b08784
--- /dev/null
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/TsKvRepository.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.dao.sql.timeseries;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.repository.CrudRepository;
+import org.thingsboard.server.dao.model.sql.TsKvCompositeKey;
+import org.thingsboard.server.dao.model.sql.TsKvEntity;
+
+@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true")
+public interface TsKvRepository extends CrudRepository<TsKvEntity, TsKvCompositeKey> {
+}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java
index c4a71b3..49f8a83 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/BaseTimeseriesService.java
@@ -72,9 +72,8 @@ public class BaseTimeseriesService implements TimeseriesService {
if (tsKvEntry == null) {
throw new IncorrectParameterException("Key value entry can't be null");
}
- long partitionTs = timeseriesDao.toPartitionTs(tsKvEntry.getTs());
List<ListenableFuture<Void>> futures = Lists.newArrayListWithExpectedSize(INSERTS_PER_ENTRY);
- saveAndRegisterFutures(futures, entityId, tsKvEntry, partitionTs, 0L);
+ saveAndRegisterFutures(futures, entityId, tsKvEntry, 0L);
return Futures.allAsList(futures);
}
@@ -85,16 +84,15 @@ public class BaseTimeseriesService implements TimeseriesService {
if (tsKvEntry == null) {
throw new IncorrectParameterException("Key value entry can't be null");
}
- long partitionTs = timeseriesDao.toPartitionTs(tsKvEntry.getTs());
- saveAndRegisterFutures(futures, entityId, tsKvEntry, partitionTs, ttl);
+ saveAndRegisterFutures(futures, entityId, tsKvEntry, ttl);
}
return Futures.allAsList(futures);
}
- private void saveAndRegisterFutures(List<ListenableFuture<Void>> futures, EntityId entityId, TsKvEntry tsKvEntry, long partitionTs, long ttl) {
- futures.add(timeseriesDao.savePartition(entityId, partitionTs, tsKvEntry.getKey(), ttl));
+ private void saveAndRegisterFutures(List<ListenableFuture<Void>> futures, EntityId entityId, TsKvEntry tsKvEntry, long ttl) {
+ futures.add(timeseriesDao.savePartition(entityId, tsKvEntry.getTs(), tsKvEntry.getKey(), ttl));
futures.add(timeseriesDao.saveLatest(entityId, tsKvEntry));
- futures.add(timeseriesDao.save(entityId, partitionTs, tsKvEntry, ttl));
+ futures.add(timeseriesDao.save(entityId, tsKvEntry, ttl));
}
private static void validate(EntityId entityId) {
diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java
index 21e01e6..bb9a1b5 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java
@@ -90,12 +90,6 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
}
@Override
- public long toPartitionTs(long ts) {
- LocalDateTime time = LocalDateTime.ofInstant(Instant.ofEpochMilli(ts), ZoneOffset.UTC);
- return tsFormat.truncatedTo(time).toInstant(ZoneOffset.UTC).toEpochMilli();
- }
-
- @Override
public ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, List<TsKvQuery> queries) {
List<ListenableFuture<List<TsKvEntry>>> futures = queries.stream().map(query -> findAllAsync(entityId, query)).collect(Collectors.toList());
return Futures.transform(Futures.allAsList(futures), new Function<List<List<TsKvEntry>>, List<TsKvEntry>>() {
@@ -163,6 +157,11 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
return resultFuture;
}
+ private long toPartitionTs(long ts) {
+ LocalDateTime time = LocalDateTime.ofInstant(Instant.ofEpochMilli(ts), ZoneOffset.UTC);
+ return tsFormat.truncatedTo(time).toInstant(ZoneOffset.UTC).toEpochMilli();
+ }
+
private void findAllAsyncSequentiallyWithLimit(final TsKvQueryCursor cursor, final SimpleListenableFuture<List<TsKvEntry>> resultFuture) {
if (cursor.isFull() || !cursor.hasNextPartition()) {
resultFuture.set(cursor.getData());
@@ -259,7 +258,8 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
}
@Override
- public ListenableFuture<Void> save(EntityId entityId, long partition, TsKvEntry tsKvEntry, long ttl) {
+ public ListenableFuture<Void> save(EntityId entityId, TsKvEntry tsKvEntry, long ttl) {
+ long partition = toPartitionTs(tsKvEntry.getTs());
DataType type = tsKvEntry.getDataType();
BoundStatement stmt = (ttl == 0 ? getSaveStmt(type) : getSaveTtlStmt(type)).bind();
stmt.setString(0, entityId.getEntityType().name())
@@ -275,7 +275,8 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
}
@Override
- public ListenableFuture<Void> savePartition(EntityId entityId, long partition, String key, long ttl) {
+ public ListenableFuture<Void> savePartition(EntityId entityId, long tsKvEntryTs, String key, long ttl) {
+ long partition = toPartitionTs(tsKvEntryTs);
log.debug("Saving partition {} for the entity [{}-{}] and key {}", partition, entityId.getEntityType(), entityId.getId(), key);
BoundStatement stmt = (ttl == 0 ? getPartitionInsertStmt() : getPartitionInsertTtlStmt()).bind();
stmt = stmt.setString(0, entityId.getEntityType().name())
diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesDao.java
index 8f1b003..5d593b7 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TimeseriesDao.java
@@ -27,17 +27,15 @@ import java.util.List;
*/
public interface TimeseriesDao {
- long toPartitionTs(long ts);
-
ListenableFuture<List<TsKvEntry>> findAllAsync(EntityId entityId, List<TsKvQuery> queries);
ListenableFuture<TsKvEntry> findLatest(EntityId entityId, String key);
ListenableFuture<List<TsKvEntry>> findAllLatest(EntityId entityId);
- ListenableFuture<Void> save(EntityId entityId, long partition, TsKvEntry tsKvEntry, long ttl);
+ ListenableFuture<Void> save(EntityId entityId, TsKvEntry tsKvEntry, long ttl);
- ListenableFuture<Void> savePartition(EntityId entityId, long partition, String key, long ttl);
+ ListenableFuture<Void> savePartition(EntityId entityId, long tsKvEntryTs, String key, long ttl);
ListenableFuture<Void> saveLatest(EntityId entityId, TsKvEntry tsKvEntry);
}
dao/src/main/resources/postgres/schema.sql 50(+38 -12)
diff --git a/dao/src/main/resources/postgres/schema.sql b/dao/src/main/resources/postgres/schema.sql
index e78199f..6791e0e 100644
--- a/dao/src/main/resources/postgres/schema.sql
+++ b/dao/src/main/resources/postgres/schema.sql
@@ -51,18 +51,6 @@ CREATE TABLE IF NOT EXISTS alarm (
);
ALTER TABLE alarm OWNER TO postgres;
-CREATE TABLE IF NOT EXISTS relation (
- from_id uuid,
- from_type character varying(255),
- to_id uuid,
- to_type character varying(255),
- relation_type_group character varying(255),
- relation_type character varying(255),
- additional_info jsonb,
- CONSTRAINT relation_unq_key UNIQUE (from_id, from_type, relation_type_group, relation_type, to_id, to_type)
-);
-ALTER TABLE relation OWNER TO postgres;
-
CREATE TABLE IF NOT EXISTS asset (
id uuid NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
additional_info jsonb,
@@ -172,6 +160,18 @@ CREATE TABLE IF NOT EXISTS plugin (
);
ALTER TABLE plugin OWNER TO postgres;
+CREATE TABLE IF NOT EXISTS relation (
+ from_id uuid,
+ from_type character varying(255),
+ to_id uuid,
+ to_type character varying(255),
+ relation_type_group character varying(255),
+ relation_type character varying(255),
+ additional_info jsonb,
+ CONSTRAINT relation_unq_key UNIQUE (from_id, from_type, relation_type_group, relation_type, to_id, to_type)
+);
+ALTER TABLE relation OWNER TO postgres;
+
CREATE TABLE IF NOT EXISTS rule (
id uuid NOT NULL CONSTRAINT rule_pkey PRIMARY KEY,
action jsonb,
@@ -217,6 +217,32 @@ CREATE TABLE IF NOT EXISTS tenant (
);
ALTER TABLE tenant OWNER TO postgres;
+CREATE TABLE IF NOT EXISTS ts_kv (
+ entity_type character varying(255) NOT NULL,
+ entity_id uuid NOT NULL,
+ key character varying(255) NOT NULL,
+ ts bigint NOT NULL,
+ bool_v boolean,
+ str_v character varying(255),
+ long_v bigint,
+ dbl_v double precision,
+ CONSTRAINT ts_kv_unq_key UNIQUE (entity_type, entity_id, key, ts)
+);
+ALTER TABLE ts_kv OWNER TO postgres;
+
+CREATE TABLE IF NOT EXISTS ts_kv_latest (
+ entity_type character varying(255) NOT NULL,
+ entity_id uuid NOT NULL,
+ key character varying(255) NOT NULL,
+ ts bigint NOT NULL,
+ bool_v boolean,
+ str_v character varying(255),
+ long_v bigint,
+ dbl_v double precision,
+ CONSTRAINT ts_kv_latest_unq_key UNIQUE (entity_type, entity_id, key)
+);
+ALTER TABLE ts_kv OWNER TO postgres;
+
CREATE TABLE IF NOT EXISTS user_credentials (
id uuid NOT NULL CONSTRAINT user_credentials_pkey PRIMARY KEY,
activate_token character varying(255) UNIQUE,