From 6a34754b3ba276cd7232da79ccbad97a4c386c2c Mon Sep 17 00:00:00 2001 From: Zhivka Dimova Date: Mon, 17 Mar 2025 15:23:48 +0100 Subject: [PATCH 1/7] [jdbc]: Fix insert time value when using persist Signed-off-by: Zhivka Dimova --- .../openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java index 95e4495cb4fa9..f6f7a6b9e389b 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java @@ -13,6 +13,7 @@ package org.openhab.persistence.jdbc.internal.db; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -131,7 +132,9 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTim String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), "?" }); - java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + String timestamp = date.format(formatter); + Object[] params = { timestamp, storedVO.getValue() }; logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); try { From 87055a41adcd95b8f7c2524aa0a4893b1f88160b Mon Sep 17 00:00:00 2001 From: Zhivka Dimova Date: Mon, 12 May 2025 21:24:07 +0200 Subject: [PATCH 2/7] [jdbc]: Use strftime and substr for parsing Signed-off-by: Zhivka Dimova --- .../persistence/jdbc/internal/db/JdbcSqliteDAO.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java index f6f7a6b9e389b..a356153a42f35 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java @@ -13,7 +13,6 @@ package org.openhab.persistence.jdbc.internal.db; import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -68,6 +67,8 @@ private void initSqlQueries() { private void initSqlTypes() { logger.debug("JDBC::initSqlTypes: Initialize the type array"); sqlTypes.put("tablePrimaryValue", "strftime('%Y-%m-%d %H:%M:%f' , 'now' , 'localtime')"); + sqlTypes.put("tablePrimaryValueFormated", + "strftime('%Y-%m-%d %H:%M:%S' , substr(?, 0, 11), 'unixepoch', 'localtime') || '.' || substr(?, 11, 3)"); } /** @@ -131,11 +132,12 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTim ItemVO storedVO = storeItemValueProvider(item, itemState, vo); String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, - new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), "?" }); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); - String timestamp = date.format(formatter); + new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), + sqlTypes.get("tablePrimaryValueParsed") }); + + java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); - Object[] params = { timestamp, storedVO.getValue() }; + Object[] params = { timestamp, timestamp, storedVO.getValue() }; logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); try { Yank.execute(sql, params); From d71e18aec976bb9daa74049173414b44fe8b95e3 Mon Sep 17 00:00:00 2001 From: Zhivka Dimova Date: Mon, 12 May 2025 21:28:40 +0200 Subject: [PATCH 3/7] [jdbc]: Remove extra empty line Signed-off-by: Zhivka Dimova --- .../org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java index a356153a42f35..5b920bd22e37d 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java @@ -136,7 +136,6 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTim sqlTypes.get("tablePrimaryValueParsed") }); java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); - Object[] params = { timestamp, timestamp, storedVO.getValue() }; logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); try { From fe0bb2ee98e415b3bc1e5d10678fbb1359d27fea Mon Sep 17 00:00:00 2001 From: Zhivka Dimova Date: Tue, 13 May 2025 10:12:02 +0200 Subject: [PATCH 4/7] [jdbc]: Replace the substr with methods Signed-off-by: Zhivka Dimova --- .../jdbc/internal/db/JdbcSqliteDAO.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java index 5b920bd22e37d..f4477f6ef59e0 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java @@ -13,6 +13,7 @@ package org.openhab.persistence.jdbc.internal.db; import java.time.ZonedDateTime; +import java.time.temporal.ChronoField; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -68,7 +69,7 @@ private void initSqlTypes() { logger.debug("JDBC::initSqlTypes: Initialize the type array"); sqlTypes.put("tablePrimaryValue", "strftime('%Y-%m-%d %H:%M:%f' , 'now' , 'localtime')"); sqlTypes.put("tablePrimaryValueFormated", - "strftime('%Y-%m-%d %H:%M:%S' , substr(?, 0, 11), 'unixepoch', 'localtime') || '.' || substr(?, 11, 3)"); + "strftime('%Y-%m-%d %H:%M:%S' , ?, 'unixepoch', 'localtime') || '.' || ?"); } /** @@ -133,11 +134,14 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTim String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), - sqlTypes.get("tablePrimaryValueParsed") }); - - java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); - Object[] params = { timestamp, timestamp, storedVO.getValue() }; - logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); + sqlTypes.get("tablePrimaryValueFormated") }); + + java.time.Instant dateInstant = date.toInstant(); + long epochSecond = dateInstant.getEpochSecond(); + int millis = dateInstant.get(ChronoField.MILLI_OF_SECOND); + Object[] params = { epochSecond, millis, storedVO.getValue() }; + logger.debug("JDBC::doStoreItemValue sql={} seconds={} millis={} value='{}'", sql, epochSecond, millis, + storedVO.getValue()); try { Yank.execute(sql, params); } catch (YankSQLException e) { From f72c06a2058b4febc7f76da80eb2483d3dda23d7 Mon Sep 17 00:00:00 2001 From: Zhivka Dimova Date: Wed, 14 May 2025 14:15:29 +0200 Subject: [PATCH 5/7] [jdbc]: Use same formarted Signed-off-by: Zhivka Dimova --- .../jdbc/internal/db/JdbcSqliteDAO.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java index f4477f6ef59e0..cb8a54a00a295 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java @@ -13,7 +13,6 @@ package org.openhab.persistence.jdbc.internal.db; import java.time.ZonedDateTime; -import java.time.temporal.ChronoField; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -43,6 +42,8 @@ public class JdbcSqliteDAO extends JdbcBaseDAO { private final Logger logger = LoggerFactory.getLogger(JdbcSqliteDAO.class); + private static final String datetimeFormat = "'%Y-%m-%d %H:%M:%f'"; + /******** * INIT * ********/ @@ -67,9 +68,8 @@ private void initSqlQueries() { */ private void initSqlTypes() { logger.debug("JDBC::initSqlTypes: Initialize the type array"); - sqlTypes.put("tablePrimaryValue", "strftime('%Y-%m-%d %H:%M:%f' , 'now' , 'localtime')"); - sqlTypes.put("tablePrimaryValueFormated", - "strftime('%Y-%m-%d %H:%M:%S' , ?, 'unixepoch', 'localtime') || '.' || ?"); + sqlTypes.put("tablePrimaryValueNow", "strftime(" + datetimeFormat + " , 'now', 'localtime')"); + sqlTypes.put("tablePrimaryValueFormated", "strftime(" + datetimeFormat + " , ?, 'unixepoch', 'localtime')"); } /** @@ -118,7 +118,7 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo) throws JdbcS String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), - sqlTypes.get("tablePrimaryValue") }); + sqlTypes.get("tablePrimaryValueNow") }); Object[] params = { storedVO.getValue() }; logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue()); try { @@ -136,11 +136,9 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTim new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), sqlTypes.get("tablePrimaryValueFormated") }); - java.time.Instant dateInstant = date.toInstant(); - long epochSecond = dateInstant.getEpochSecond(); - int millis = dateInstant.get(ChronoField.MILLI_OF_SECOND); - Object[] params = { epochSecond, millis, storedVO.getValue() }; - logger.debug("JDBC::doStoreItemValue sql={} seconds={} millis={} value='{}'", sql, epochSecond, millis, + double epochSecondsWithMillis = date.toInstant().toEpochMilli() / 1_000.0; + Object[] params = { epochSecondsWithMillis, storedVO.getValue() }; + logger.debug("JDBC::doStoreItemValue sql={} epochSecondsWithMillis={} value='{}'", sql, epochSecondsWithMillis, storedVO.getValue()); try { Yank.execute(sql, params); From 5dcdd02055b39b89decfbd5db15d5af0d249a52c Mon Sep 17 00:00:00 2001 From: Zhivka Dimova Date: Wed, 14 May 2025 15:16:07 +0200 Subject: [PATCH 6/7] [jdbc]: Remove tablePrimaryValueFormated from sqlTypes Signed-off-by: Zhivka Dimova --- .../persistence/jdbc/internal/db/JdbcSqliteDAO.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java index cb8a54a00a295..cf98b4e6cd9d5 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java @@ -68,8 +68,7 @@ private void initSqlQueries() { */ private void initSqlTypes() { logger.debug("JDBC::initSqlTypes: Initialize the type array"); - sqlTypes.put("tablePrimaryValueNow", "strftime(" + datetimeFormat + " , 'now', 'localtime')"); - sqlTypes.put("tablePrimaryValueFormated", "strftime(" + datetimeFormat + " , ?, 'unixepoch', 'localtime')"); + sqlTypes.put("tablePrimaryValue", "strftime(" + datetimeFormat + " , 'now', 'localtime')"); } /** @@ -118,7 +117,7 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo) throws JdbcS String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), - sqlTypes.get("tablePrimaryValueNow") }); + sqlTypes.get("tablePrimaryValue") }); Object[] params = { storedVO.getValue() }; logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue()); try { @@ -134,7 +133,7 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTim String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), - sqlTypes.get("tablePrimaryValueFormated") }); + "strftime(" + datetimeFormat + " , ?, 'unixepoch', 'localtime')" }); double epochSecondsWithMillis = date.toInstant().toEpochMilli() / 1_000.0; Object[] params = { epochSecondsWithMillis, storedVO.getValue() }; From 4f7ad2ed8fe44f565309fb6350a0a191f16e674a Mon Sep 17 00:00:00 2001 From: Zhivka Dimova Date: Wed, 14 May 2025 15:56:51 +0200 Subject: [PATCH 7/7] [jdbc]: Complying with the naming convention Signed-off-by: Zhivka Dimova --- .../openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java index cf98b4e6cd9d5..3558513103250 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java @@ -42,7 +42,7 @@ public class JdbcSqliteDAO extends JdbcBaseDAO { private final Logger logger = LoggerFactory.getLogger(JdbcSqliteDAO.class); - private static final String datetimeFormat = "'%Y-%m-%d %H:%M:%f'"; + private static final String DATETIME_FORMAT = "'%Y-%m-%d %H:%M:%f'"; /******** * INIT * @@ -68,7 +68,7 @@ private void initSqlQueries() { */ private void initSqlTypes() { logger.debug("JDBC::initSqlTypes: Initialize the type array"); - sqlTypes.put("tablePrimaryValue", "strftime(" + datetimeFormat + " , 'now', 'localtime')"); + sqlTypes.put("tablePrimaryValue", "strftime(" + DATETIME_FORMAT + " , 'now', 'localtime')"); } /** @@ -133,7 +133,7 @@ public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTim String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), - "strftime(" + datetimeFormat + " , ?, 'unixepoch', 'localtime')" }); + "strftime(" + DATETIME_FORMAT + " , ?, 'unixepoch', 'localtime')" }); double epochSecondsWithMillis = date.toInstant().toEpochMilli() / 1_000.0; Object[] params = { epochSecondsWithMillis, storedVO.getValue() };