[jdbc] Consider local timezone to create time filter (#9445)

* Consider local timezone to create time filter
* Use user-defined timeZone

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
Christoph Weitkamp 2020-12-24 02:19:08 +01:00 committed by GitHub
parent dfc2fa7cfc
commit 133df3aa40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 29 deletions

View File

@ -330,8 +330,8 @@ public class JdbcBaseDAO {
} }
public List<HistoricItem> doGetHistItemFilterQuery(Item item, FilterCriteria filter, int numberDecimalcount, public List<HistoricItem> doGetHistItemFilterQuery(Item item, FilterCriteria filter, int numberDecimalcount,
String table, String name) { String table, String name, ZoneId timeZone) {
String sql = histItemFilterQueryProvider(filter, numberDecimalcount, table, name); String sql = histItemFilterQueryProvider(filter, numberDecimalcount, table, name, timeZone);
logger.debug("JDBC::doGetHistItemFilterQuery sql={}", sql); logger.debug("JDBC::doGetHistItemFilterQuery sql={}", sql);
List<Object[]> m = Yank.queryObjectArrays(sql, null); List<Object[]> m = Yank.queryObjectArrays(sql, null);
@ -348,7 +348,7 @@ public class JdbcBaseDAO {
static final DateTimeFormatter JDBC_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); static final DateTimeFormatter JDBC_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private String histItemFilterQueryProvider(FilterCriteria filter, int numberDecimalcount, String table, private String histItemFilterQueryProvider(FilterCriteria filter, int numberDecimalcount, String table,
String simpleName) { String simpleName, ZoneId timeZone) {
logger.debug( logger.debug(
"JDBC::getHistItemFilterQueryProvider filter = {}, numberDecimalcount = {}, table = {}, simpleName = {}", "JDBC::getHistItemFilterQueryProvider filter = {}, numberDecimalcount = {}, table = {}, simpleName = {}",
filter.toString(), numberDecimalcount, table, simpleName); filter.toString(), numberDecimalcount, table, simpleName);
@ -356,11 +356,13 @@ public class JdbcBaseDAO {
String filterString = ""; String filterString = "";
if (filter.getBeginDate() != null) { if (filter.getBeginDate() != null) {
filterString += filterString.isEmpty() ? " WHERE" : " AND"; filterString += filterString.isEmpty() ? " WHERE" : " AND";
filterString += " TIME>'" + JDBC_DATE_FORMAT.format(filter.getBeginDate()) + "'"; filterString += " TIME>'" + JDBC_DATE_FORMAT.format(filter.getBeginDate().withZoneSameInstant(timeZone))
+ "'";
} }
if (filter.getEndDate() != null) { if (filter.getEndDate() != null) {
filterString += filterString.isEmpty() ? " WHERE" : " AND"; filterString += filterString.isEmpty() ? " WHERE" : " AND";
filterString += " TIME<'" + JDBC_DATE_FORMAT.format(filter.getEndDate()) + "'"; filterString += " TIME<'" + JDBC_DATE_FORMAT.format(filter.getEndDate().withZoneSameInstant(timeZone))
+ "'";
} }
filterString += (filter.getOrdering() == Ordering.ASCENDING) ? " ORDER BY time ASC" : " ORDER BY time DESC "; filterString += (filter.getOrdering() == Ordering.ASCENDING) ? " ORDER BY time ASC" : " ORDER BY time DESC ";
if (filter.getPageSize() != 0x7fffffff) { if (filter.getPageSize() != 0x7fffffff) {

View File

@ -12,6 +12,7 @@
*/ */
package org.openhab.persistence.jdbc.db; package org.openhab.persistence.jdbc.db;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -156,8 +157,8 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
@Override @Override
public List<HistoricItem> doGetHistItemFilterQuery(Item item, FilterCriteria filter, int numberDecimalcount, public List<HistoricItem> doGetHistItemFilterQuery(Item item, FilterCriteria filter, int numberDecimalcount,
String table, String name) { String table, String name, ZoneId timeZone) {
String sql = histItemFilterQueryProvider(filter, numberDecimalcount, table, name); String sql = histItemFilterQueryProvider(filter, numberDecimalcount, table, name, timeZone);
List<Object[]> m = Yank.queryObjectArrays(sql, null); List<Object[]> m = Yank.queryObjectArrays(sql, null);
logger.debug("JDBC::doGetHistItemFilterQuery got Array length={}", m.size()); logger.debug("JDBC::doGetHistItemFilterQuery got Array length={}", m.size());
@ -175,14 +176,8 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
****************************/ ****************************/
static final DateTimeFormatter JDBC_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); static final DateTimeFormatter JDBC_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* @param filter
* @param numberDecimalcount
* @param table
* @return
*/
private String histItemFilterQueryProvider(FilterCriteria filter, int numberDecimalcount, String table, private String histItemFilterQueryProvider(FilterCriteria filter, int numberDecimalcount, String table,
String simpleName) { String simpleName, ZoneId timeZone) {
logger.debug( logger.debug(
"JDBC::getHistItemFilterQueryProvider filter = {}, numberDecimalcount = {}, table = {}, simpleName = {}", "JDBC::getHistItemFilterQueryProvider filter = {}, numberDecimalcount = {}, table = {}, simpleName = {}",
StringUtilsExt.filterToString(filter), numberDecimalcount, table, simpleName); StringUtilsExt.filterToString(filter), numberDecimalcount, table, simpleName);
@ -190,11 +185,13 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
String filterString = ""; String filterString = "";
if (filter.getBeginDate() != null) { if (filter.getBeginDate() != null) {
filterString += filterString.isEmpty() ? " WHERE" : " AND"; filterString += filterString.isEmpty() ? " WHERE" : " AND";
filterString += " TIME>'" + JDBC_DATE_FORMAT.format(filter.getBeginDate()) + "'"; filterString += " TIME>'" + JDBC_DATE_FORMAT.format(filter.getBeginDate().withZoneSameInstant(timeZone))
+ "'";
} }
if (filter.getEndDate() != null) { if (filter.getEndDate() != null) {
filterString += filterString.isEmpty() ? " WHERE" : " AND"; filterString += filterString.isEmpty() ? " WHERE" : " AND";
filterString += " TIME<'" + JDBC_DATE_FORMAT.format(filter.getEndDate()) + "'"; filterString += " TIME<'" + JDBC_DATE_FORMAT.format(filter.getEndDate().withZoneSameInstant(timeZone))
+ "'";
} }
filterString += (filter.getOrdering() == Ordering.ASCENDING) ? " ORDER BY time ASC" : " ORDER BY time DESC"; filterString += (filter.getOrdering() == Ordering.ASCENDING) ? " ORDER BY time ASC" : " ORDER BY time DESC";
if (filter.getPageSize() != 0x7fffffff) { if (filter.getPageSize() != 0x7fffffff) {

View File

@ -12,6 +12,7 @@
*/ */
package org.openhab.persistence.jdbc.db; package org.openhab.persistence.jdbc.db;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -146,8 +147,8 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
@Override @Override
public List<HistoricItem> doGetHistItemFilterQuery(Item item, FilterCriteria filter, int numberDecimalcount, public List<HistoricItem> doGetHistItemFilterQuery(Item item, FilterCriteria filter, int numberDecimalcount,
String table, String name) { String table, String name, ZoneId timeZone) {
String sql = histItemFilterQueryProvider(filter, numberDecimalcount, table, name); String sql = histItemFilterQueryProvider(filter, numberDecimalcount, table, name, timeZone);
logger.debug("JDBC::doGetHistItemFilterQuery sql={}", sql); logger.debug("JDBC::doGetHistItemFilterQuery sql={}", sql);
List<Object[]> m = Yank.queryObjectArrays(sql, null); List<Object[]> m = Yank.queryObjectArrays(sql, null);
@ -163,14 +164,8 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
****************************/ ****************************/
static final DateTimeFormatter JDBC_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); static final DateTimeFormatter JDBC_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* @param filter
* @param numberDecimalcount
* @param table
* @return
*/
private String histItemFilterQueryProvider(FilterCriteria filter, int numberDecimalcount, String table, private String histItemFilterQueryProvider(FilterCriteria filter, int numberDecimalcount, String table,
String simpleName) { String simpleName, ZoneId timeZone) {
logger.debug( logger.debug(
"JDBC::getHistItemFilterQueryProvider filter = {}, numberDecimalcount = {}, table = {}, simpleName = {}", "JDBC::getHistItemFilterQueryProvider filter = {}, numberDecimalcount = {}, table = {}, simpleName = {}",
filter.toString(), numberDecimalcount, table, simpleName); filter.toString(), numberDecimalcount, table, simpleName);
@ -178,11 +173,13 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
String filterString = ""; String filterString = "";
if (filter.getBeginDate() != null) { if (filter.getBeginDate() != null) {
filterString += filterString.isEmpty() ? " WHERE" : " AND"; filterString += filterString.isEmpty() ? " WHERE" : " AND";
filterString += " TIME>'" + JDBC_DATE_FORMAT.format(filter.getBeginDate()) + "'"; filterString += " TIME>'" + JDBC_DATE_FORMAT.format(filter.getBeginDate().withZoneSameInstant(timeZone))
+ "'";
} }
if (filter.getEndDate() != null) { if (filter.getEndDate() != null) {
filterString += filterString.isEmpty() ? " WHERE" : " AND"; filterString += filterString.isEmpty() ? " WHERE" : " AND";
filterString += " TIME<'" + JDBC_DATE_FORMAT.format(filter.getEndDate()) + "'"; filterString += " TIME<'" + JDBC_DATE_FORMAT.format(filter.getEndDate().withZoneSameInstant(timeZone))
+ "'";
} }
filterString += (filter.getOrdering() == Ordering.ASCENDING) ? " ORDER BY time ASC" : " ORDER BY time DESC"; filterString += (filter.getOrdering() == Ordering.ASCENDING) ? " ORDER BY time ASC" : " ORDER BY time DESC";
if (filter.getPageSize() != 0x7fffffff) { if (filter.getPageSize() != 0x7fffffff) {

View File

@ -20,6 +20,7 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.knowm.yank.Yank; import org.knowm.yank.Yank;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.items.Item; import org.openhab.core.items.Item;
import org.openhab.core.persistence.FilterCriteria; import org.openhab.core.persistence.FilterCriteria;
import org.openhab.core.persistence.HistoricItem; import org.openhab.core.persistence.HistoricItem;
@ -38,6 +39,8 @@ import org.slf4j.LoggerFactory;
public class JdbcMapper { public class JdbcMapper {
private final Logger logger = LoggerFactory.getLogger(JdbcMapper.class); private final Logger logger = LoggerFactory.getLogger(JdbcMapper.class);
private final TimeZoneProvider timeZoneProvider;
// Error counter - used to reconnect to database on error // Error counter - used to reconnect to database on error
protected int errCnt; protected int errCnt;
protected boolean initialized = false; protected boolean initialized = false;
@ -47,6 +50,10 @@ public class JdbcMapper {
private long afterAccessMax = 0; private long afterAccessMax = 0;
private static final String ITEM_NAME_PATTERN = "[^a-zA-Z_0-9\\-]"; private static final String ITEM_NAME_PATTERN = "[^a-zA-Z_0-9\\-]";
public JdbcMapper(TimeZoneProvider timeZoneProvider) {
this.timeZoneProvider = timeZoneProvider;
}
/***************** /*****************
* MAPPER ITEMS * * MAPPER ITEMS *
*****************/ *****************/
@ -160,7 +167,7 @@ public class JdbcMapper {
if (table != null) { if (table != null) {
long timerStart = System.currentTimeMillis(); long timerStart = System.currentTimeMillis();
List<HistoricItem> r = conf.getDBDAO().doGetHistItemFilterQuery(item, filter, numberDecimalcount, table, List<HistoricItem> r = conf.getDBDAO().doGetHistItemFilterQuery(item, filter, numberDecimalcount, table,
item.getName()); item.getName(), timeZoneProvider.getTimeZone());
logTime("insertItemValue", timerStart, System.currentTimeMillis()); logTime("insertItemValue", timerStart, System.currentTimeMillis());
return r; return r;
} else { } else {

View File

@ -20,6 +20,7 @@ import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.config.core.ConfigurableService; import org.openhab.core.config.core.ConfigurableService;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.items.GroupItem; import org.openhab.core.items.GroupItem;
import org.openhab.core.items.Item; import org.openhab.core.items.Item;
import org.openhab.core.items.ItemNotFoundException; import org.openhab.core.items.ItemNotFoundException;
@ -60,7 +61,9 @@ public class JdbcPersistenceService extends JdbcMapper implements QueryablePersi
private final ItemRegistry itemRegistry; private final ItemRegistry itemRegistry;
@Activate @Activate
public JdbcPersistenceService(final @Reference ItemRegistry itemRegistry) { public JdbcPersistenceService(final @Reference ItemRegistry itemRegistry,
final @Reference TimeZoneProvider timeZoneProvider) {
super(timeZoneProvider);
this.itemRegistry = itemRegistry; this.itemRegistry = itemRegistry;
} }