[jdbc] Fix case-sensitive table names for PostgreSQL (#17597)

* Fix case-sensitive table names for PostgreSQL

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
Jacob Laursen 2024-10-21 23:48:59 +02:00 committed by GitHub
parent eac49a836f
commit 63cdc9576c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 87 additions and 160 deletions

View File

@ -79,7 +79,7 @@ All item- and event-related configuration is done in the file `persistence/jdbc.
To configure this service as the default persistence service for openHAB, add or change the line To configure this service as the default persistence service for openHAB, add or change the line
``` ```ini
org.openhab.core.persistence:default=jdbc org.openhab.core.persistence:default=jdbc
``` ```
@ -89,7 +89,7 @@ in the file `services/runtime.cfg`.
services/jdbc.cfg services/jdbc.cfg
``` ```ini
url=jdbc:postgresql://192.168.0.1:5432/testPostgresql url=jdbc:postgresql://192.168.0.1:5432/testPostgresql
``` ```
@ -102,7 +102,7 @@ To connect to an Oracle Autonomous Database, use the instructions at https://www
Your services/jdbc.cfg should contain the following minimal configuration for connecting to an Oracle Autonomous Database: Your services/jdbc.cfg should contain the following minimal configuration for connecting to an Oracle Autonomous Database:
``` ```ini
url=jdbc:oracle:thin:@dbname?TNS_ADMIN=./dbname_tns_admin_folder url=jdbc:oracle:thin:@dbname?TNS_ADMIN=./dbname_tns_admin_folder
user=openhab user=openhab
password=openhab_password password=openhab_password
@ -147,7 +147,7 @@ Here is an example of a configuration for a MySQL database named `testMysql` wit
services/jdbc.cfg services/jdbc.cfg
``` ```ini
url=jdbc:mysql://192.168.0.1:3306/testMysql url=jdbc:mysql://192.168.0.1:3306/testMysql
user=test user=test
password=test password=test

View File

@ -296,7 +296,7 @@ public class JdbcBaseDAO {
public Long doCreateNewEntryInItemsTable(ItemsVO vo) throws JdbcSQLException { public Long doCreateNewEntryInItemsTable(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateNewEntryInItemsTable, String sql = StringUtilsExt.replaceArrayMerge(sqlCreateNewEntryInItemsTable,
new String[] { "#itemsManageTable#", "#itemname#" }, new String[] { "#itemsManageTable#", "#itemname#" },
new String[] { vo.getItemsManageTable(), vo.getItemName() }); new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getItemName() });
logger.debug("JDBC::doCreateNewEntryInItemsTable sql={}", sql); logger.debug("JDBC::doCreateNewEntryInItemsTable sql={}", sql);
try { try {
return Yank.insert(sql, null); return Yank.insert(sql, null);
@ -308,7 +308,7 @@ public class JdbcBaseDAO {
public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException { public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot, String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot,
new String[] { "#itemsManageTable#", "#colname#", "#coltype#" }, new String[] { "#itemsManageTable#", "#colname#", "#coltype#" },
new String[] { vo.getItemsManageTable(), vo.getColname(), vo.getColtype() }); new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getColname(), vo.getColtype() });
logger.debug("JDBC::doCreateItemsTableIfNot sql={}", sql); logger.debug("JDBC::doCreateItemsTableIfNot sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -320,7 +320,7 @@ public class JdbcBaseDAO {
public ItemsVO doDropItemsTableIfExists(ItemsVO vo) throws JdbcSQLException { public ItemsVO doDropItemsTableIfExists(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlDropItemsTableIfExists, new String[] { "#itemsManageTable#" }, String sql = StringUtilsExt.replaceArrayMerge(sqlDropItemsTableIfExists, new String[] { "#itemsManageTable#" },
new String[] { vo.getItemsManageTable() }); new String[] { formattedIdentifier(vo.getItemsManageTable()) });
logger.debug("JDBC::doDropItemsTableIfExists sql={}", sql); logger.debug("JDBC::doDropItemsTableIfExists sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -332,7 +332,7 @@ public class JdbcBaseDAO {
public void doDropTable(String tableName) throws JdbcSQLException { public void doDropTable(String tableName) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlDropTable, new String[] { "#tableName#" }, String sql = StringUtilsExt.replaceArrayMerge(sqlDropTable, new String[] { "#tableName#" },
new String[] { tableName }); new String[] { formattedIdentifier(tableName) });
logger.debug("JDBC::doDropTable sql={}", sql); logger.debug("JDBC::doDropTable sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -344,7 +344,7 @@ public class JdbcBaseDAO {
public void doDeleteItemsEntry(ItemsVO vo) throws JdbcSQLException { public void doDeleteItemsEntry(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlDeleteItemsEntry, String sql = StringUtilsExt.replaceArrayMerge(sqlDeleteItemsEntry,
new String[] { "#itemsManageTable#", "#itemname#" }, new String[] { "#itemsManageTable#", "#itemname#" },
new String[] { vo.getItemsManageTable(), vo.getItemName() }); new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getItemName() });
logger.debug("JDBC::doDeleteItemsEntry sql={}", sql); logger.debug("JDBC::doDeleteItemsEntry sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -355,7 +355,7 @@ public class JdbcBaseDAO {
public List<ItemsVO> doGetItemIDTableNames(ItemsVO vo) throws JdbcSQLException { public List<ItemsVO> doGetItemIDTableNames(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlGetItemIDTableNames, new String[] { "#itemsManageTable#" }, String sql = StringUtilsExt.replaceArrayMerge(sqlGetItemIDTableNames, new String[] { "#itemsManageTable#" },
new String[] { vo.getItemsManageTable() }); new String[] { formattedIdentifier(vo.getItemsManageTable()) });
logger.debug("JDBC::doGetItemIDTableNames sql={}", sql); logger.debug("JDBC::doGetItemIDTableNames sql={}", sql);
try { try {
return Yank.queryBeanList(sql, ItemsVO.class, null); return Yank.queryBeanList(sql, ItemsVO.class, null);
@ -405,8 +405,8 @@ public class JdbcBaseDAO {
public void doCreateItemTable(ItemVO vo) throws JdbcSQLException { public void doCreateItemTable(ItemVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemTable, String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemTable,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryKey#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryKey#" }, new String[] {
new String[] { vo.getTableName(), vo.getDbType(), sqlTypes.get("tablePrimaryKey") }); formattedIdentifier(vo.getTableName()), vo.getDbType(), sqlTypes.get("tablePrimaryKey") });
logger.debug("JDBC::doCreateItemTable sql={}", sql); logger.debug("JDBC::doCreateItemTable sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -418,8 +418,8 @@ public class JdbcBaseDAO {
public void doAlterTableColumn(String tableName, String columnName, String columnType, boolean nullable) public void doAlterTableColumn(String tableName, String columnName, String columnType, boolean nullable)
throws JdbcSQLException { throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlAlterTableColumn, String sql = StringUtilsExt.replaceArrayMerge(sqlAlterTableColumn,
new String[] { "#tableName#", "#columnName#", "#columnType#" }, new String[] { "#tableName#", "#columnName#", "#columnType#" }, new String[] {
new String[] { tableName, columnName, nullable ? columnType : columnType + " NOT NULL" }); formattedIdentifier(tableName), columnName, nullable ? columnType : columnType + " NOT NULL" });
logger.debug("JDBC::doAlterTableColumn sql={}", sql); logger.debug("JDBC::doAlterTableColumn sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -432,7 +432,7 @@ public class JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), sqlTypes.get("tablePrimaryValue") }); new String[] { formattedIdentifier(storedVO.getTableName()), sqlTypes.get("tablePrimaryValue") });
Object[] params = { storedVO.getValue(), storedVO.getValue() }; Object[] params = { storedVO.getValue(), storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
try { try {
@ -445,7 +445,8 @@ public class JdbcBaseDAO {
public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTime date) throws JdbcSQLException { public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTime date) throws JdbcSQLException {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#tablePrimaryValue#" }, new String[] { storedVO.getTableName(), "?" }); new String[] { "#tableName#", "#tablePrimaryValue#" },
new String[] { formattedIdentifier(storedVO.getTableName()), "?" });
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli());
Object[] params = { timestamp, storedVO.getValue(), storedVO.getValue() }; Object[] params = { timestamp, storedVO.getValue(), storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());
@ -490,7 +491,7 @@ public class JdbcBaseDAO {
public long doGetRowCount(String tableName) throws JdbcSQLException { public long doGetRowCount(String tableName) throws JdbcSQLException {
final String sql = StringUtilsExt.replaceArrayMerge(sqlGetRowCount, new String[] { "#tableName#" }, final String sql = StringUtilsExt.replaceArrayMerge(sqlGetRowCount, new String[] { "#tableName#" },
new String[] { tableName }); new String[] { formattedIdentifier(tableName) });
logger.debug("JDBC::doGetRowCount sql={}", sql); logger.debug("JDBC::doGetRowCount sql={}", sql);
try { try {
final @Nullable Long result = Yank.queryScalar(sql, Long.class, null); final @Nullable Long result = Yank.queryScalar(sql, Long.class, null);
@ -519,8 +520,8 @@ public class JdbcBaseDAO {
// SELECT time, ROUND(value,3) FROM number_item_0114 ORDER BY time DESC LIMIT 0,1 // SELECT time, ROUND(value,3) FROM number_item_0114 ORDER BY time DESC LIMIT 0,1
// rounding HALF UP // rounding HALF UP
String queryString = "NUMBERITEM".equalsIgnoreCase(simpleName) && numberDecimalcount > -1 String queryString = "NUMBERITEM".equalsIgnoreCase(simpleName) && numberDecimalcount > -1
? "SELECT time, ROUND(value," + numberDecimalcount + ") FROM " + table ? "SELECT time, ROUND(value," + numberDecimalcount + ") FROM " + formattedIdentifier(table)
: "SELECT time, value FROM " + table; : "SELECT time, value FROM " + formattedIdentifier(table);
if (!filterString.isEmpty()) { if (!filterString.isEmpty()) {
queryString += filterString; queryString += filterString;
} }
@ -532,8 +533,8 @@ public class JdbcBaseDAO {
logger.debug("JDBC::histItemFilterDeleteProvider filter = {}, table = {}", filter, table); logger.debug("JDBC::histItemFilterDeleteProvider filter = {}, table = {}", filter, table);
String filterString = resolveTimeFilter(filter, timeZone); String filterString = resolveTimeFilter(filter, timeZone);
String deleteString = filterString.isEmpty() ? "TRUNCATE TABLE " + table String deleteString = filterString.isEmpty() ? "TRUNCATE TABLE " + formattedIdentifier(table)
: "DELETE FROM " + table + filterString; : "DELETE FROM " + formattedIdentifier(table) + filterString;
logger.debug("JDBC::delete deleteString = {}", deleteString); logger.debug("JDBC::delete deleteString = {}", deleteString);
return deleteString; return deleteString;
} }
@ -554,7 +555,12 @@ public class JdbcBaseDAO {
} }
private String updateItemTableNamesProvider(ItemVO itemTable) { private String updateItemTableNamesProvider(ItemVO itemTable) {
String queryString = "ALTER TABLE " + itemTable.getTableName() + " RENAME TO " + itemTable.getNewTableName(); String newTableName = itemTable.getNewTableName();
if (newTableName == null) {
throw new IllegalArgumentException("New table name is not provided");
}
String queryString = "ALTER TABLE " + formattedIdentifier(itemTable.getTableName()) + " RENAME TO "
+ formattedIdentifier(newTableName);
logger.debug("JDBC::query queryString = {}", queryString); logger.debug("JDBC::query queryString = {}", queryString);
return queryString; return queryString;
} }
@ -757,7 +763,11 @@ public class JdbcBaseDAO {
throw new UnsupportedOperationException("String of type '" + v.getClass().getName() + "' is not supported"); throw new UnsupportedOperationException("String of type '" + v.getClass().getName() + "' is not supported");
} }
public String getItemType(Item i) { protected String formattedIdentifier(String identifier) {
return identifier;
}
private String getItemType(Item i) {
Item item = i; Item item = i;
String def = "STRINGITEM"; String def = "STRINGITEM";
if (i instanceof GroupItem groupItem) { if (i instanceof GroupItem groupItem) {

View File

@ -14,26 +14,18 @@ package org.openhab.persistence.jdbc.internal.db;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
import javax.measure.Quantity;
import javax.measure.Unit;
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.knowm.yank.Yank; import org.knowm.yank.Yank;
import org.knowm.yank.exceptions.YankSQLException; import org.knowm.yank.exceptions.YankSQLException;
import org.openhab.core.items.Item; import org.openhab.core.items.Item;
import org.openhab.core.library.items.NumberItem;
import org.openhab.core.persistence.FilterCriteria; import org.openhab.core.persistence.FilterCriteria;
import org.openhab.core.persistence.FilterCriteria.Ordering; import org.openhab.core.persistence.FilterCriteria.Ordering;
import org.openhab.core.persistence.HistoricItem;
import org.openhab.core.types.State; import org.openhab.core.types.State;
import org.openhab.persistence.jdbc.internal.dto.ItemVO; import org.openhab.persistence.jdbc.internal.dto.ItemVO;
import org.openhab.persistence.jdbc.internal.dto.ItemsVO; import org.openhab.persistence.jdbc.internal.dto.ItemsVO;
import org.openhab.persistence.jdbc.internal.dto.JdbcHistoricItem;
import org.openhab.persistence.jdbc.internal.exceptions.JdbcSQLException; import org.openhab.persistence.jdbc.internal.exceptions.JdbcSQLException;
import org.openhab.persistence.jdbc.internal.utils.StringUtilsExt; import org.openhab.persistence.jdbc.internal.utils.StringUtilsExt;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -121,7 +113,7 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
@Override @Override
public boolean doIfTableExists(ItemsVO vo) throws JdbcSQLException { public boolean doIfTableExists(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlIfTableExists, new String[] { "#searchTable#" }, String sql = StringUtilsExt.replaceArrayMerge(sqlIfTableExists, new String[] { "#searchTable#" },
new String[] { vo.getItemsManageTable().toUpperCase() }); new String[] { formattedIdentifier(vo.getItemsManageTable()) });
logger.debug("JDBC::doIfTableExists sql={}", sql); logger.debug("JDBC::doIfTableExists sql={}", sql);
try { try {
final @Nullable String result = Yank.queryScalar(sql, String.class, null); final @Nullable String result = Yank.queryScalar(sql, String.class, null);
@ -131,26 +123,13 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
} }
} }
@Override
public Long doCreateNewEntryInItemsTable(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateNewEntryInItemsTable,
new String[] { "#itemsManageTable#", "#itemname#" },
new String[] { vo.getItemsManageTable().toUpperCase(), vo.getItemName() });
logger.debug("JDBC::doCreateNewEntryInItemsTable sql={}", sql);
try {
return Yank.insert(sql, null);
} catch (YankSQLException e) {
throw new JdbcSQLException(e);
}
}
@Override @Override
public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException { public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException {
boolean tableExists = doIfTableExists(vo); boolean tableExists = doIfTableExists(vo);
if (!tableExists) { if (!tableExists) {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot, String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot,
new String[] { "#itemsManageTable#", "#colname#", "#coltype#" }, new String[] { "#itemsManageTable#", "#colname#", "#coltype#" },
new String[] { vo.getItemsManageTable().toUpperCase(), vo.getColname(), vo.getColtype() }); new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getColname(), vo.getColtype() });
logger.debug("JDBC::doCreateItemsTableIfNot tableExists={} therefore sql={}", tableExists, sql); logger.debug("JDBC::doCreateItemsTableIfNot tableExists={} therefore sql={}", tableExists, sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -166,24 +145,12 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
/************* /*************
* ITEM DAOs * * ITEM DAOs *
*************/ *************/
@Override
public void doCreateItemTable(ItemVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemTable,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryKey#" },
new String[] { vo.getTableName(), vo.getDbType(), sqlTypes.get("tablePrimaryKey") });
try {
Yank.execute(sql, null);
} catch (YankSQLException e) {
throw new JdbcSQLException(e);
}
}
@Override @Override
public void doStoreItemValue(Item item, State itemState, ItemVO vo) throws JdbcSQLException { public void doStoreItemValue(Item item, State itemState, ItemVO vo) throws JdbcSQLException {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName().toUpperCase(), storedVO.getDbType(), new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(),
sqlTypes.get("tablePrimaryValue") }); sqlTypes.get("tablePrimaryValue") });
Object[] params = { storedVO.getValue() }; Object[] params = { storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
@ -199,7 +166,7 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName().toUpperCase(), storedVO.getDbType(), "?" }); new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), "?" });
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli());
Object[] params = { timestamp, storedVO.getValue() }; Object[] params = { timestamp, storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());
@ -210,26 +177,6 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
} }
} }
@Override
public List<HistoricItem> doGetHistItemFilterQuery(Item item, FilterCriteria filter, int numberDecimalcount,
String table, String name, ZoneId timeZone) throws JdbcSQLException {
String sql = histItemFilterQueryProvider(filter, numberDecimalcount, table, name, timeZone);
List<Object[]> m;
try {
m = Yank.queryObjectArrays(sql, null);
} catch (YankSQLException e) {
throw new JdbcSQLException(e);
}
logger.debug("JDBC::doGetHistItemFilterQuery got Array length={}", m.size());
// we already retrieve the unit here once as it is a very costly operation
String itemName = item.getName();
Unit<? extends Quantity<?>> unit = item instanceof NumberItem ni ? ni.getUnit() : null;
return m.stream().map(o -> {
logger.debug("JDBC::doGetHistItemFilterQuery 0='{}' 1='{}'", o[0], o[1]);
return new JdbcHistoricItem(itemName, objectAsState(item, unit, o[1]), objectAsZonedDateTime(o[0]));
}).collect(Collectors.<HistoricItem> toList());
}
/**************************** /****************************
* SQL generation Providers * * SQL generation Providers *
****************************/ ****************************/
@ -280,7 +227,7 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
queryString += "5 AS DECIMAL(31," + numberDecimalcount + "))"; // 31 is DECIMAL max precision queryString += "5 AS DECIMAL(31," + numberDecimalcount + "))"; // 31 is DECIMAL max precision
// https://db.apache.org/derby/docs/10.0/manuals/develop/develop151.html // https://db.apache.org/derby/docs/10.0/manuals/develop/develop151.html
} else { } else {
queryString += " value FROM " + table.toUpperCase(); queryString += " value FROM " + formattedIdentifier(table);
} }
if (!filterString.isEmpty()) { if (!filterString.isEmpty()) {
@ -293,6 +240,10 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
/***************** /*****************
* H E L P E R S * * H E L P E R S *
*****************/ *****************/
@Override
protected String formattedIdentifier(String identifier) {
return identifier.toUpperCase();
}
/****************************** /******************************
* public Getters and Setters * * public Getters and Setters *

View File

@ -85,7 +85,8 @@ public class JdbcH2DAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), storedVO.getDbType(), sqlTypes.get("tablePrimaryValue") }); new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(),
sqlTypes.get("tablePrimaryValue") });
Object[] params = { storedVO.getValue() }; Object[] params = { storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
try { try {
@ -100,7 +101,7 @@ public class JdbcH2DAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), storedVO.getDbType(), "?" }); new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), "?" });
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli());
Object[] params = { timestamp, storedVO.getValue() }; Object[] params = { timestamp, storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());

View File

@ -21,7 +21,6 @@ import org.knowm.yank.exceptions.YankSQLException;
import org.openhab.core.items.Item; import org.openhab.core.items.Item;
import org.openhab.core.types.State; import org.openhab.core.types.State;
import org.openhab.persistence.jdbc.internal.dto.ItemVO; import org.openhab.persistence.jdbc.internal.dto.ItemVO;
import org.openhab.persistence.jdbc.internal.dto.ItemsVO;
import org.openhab.persistence.jdbc.internal.exceptions.JdbcSQLException; import org.openhab.persistence.jdbc.internal.exceptions.JdbcSQLException;
import org.openhab.persistence.jdbc.internal.utils.StringUtilsExt; import org.openhab.persistence.jdbc.internal.utils.StringUtilsExt;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -97,33 +96,6 @@ public class JdbcHsqldbDAO extends JdbcBaseDAO {
} }
} }
@Override
public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot,
new String[] { "#itemsManageTable#", "#colname#", "#coltype#", "#itemsManageTable#" },
new String[] { vo.getItemsManageTable(), vo.getColname(), vo.getColtype(), vo.getItemsManageTable() });
logger.debug("JDBC::doCreateItemsTableIfNot sql={}", sql);
try {
Yank.execute(sql, null);
} catch (YankSQLException e) {
throw new JdbcSQLException(e);
}
return vo;
}
@Override
public Long doCreateNewEntryInItemsTable(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateNewEntryInItemsTable,
new String[] { "#itemsManageTable#", "#itemname#" },
new String[] { vo.getItemsManageTable(), vo.getItemName() });
logger.debug("JDBC::doCreateNewEntryInItemsTable sql={}", sql);
try {
return Yank.insert(sql, null);
} catch (YankSQLException e) {
throw new JdbcSQLException(e);
}
}
/************* /*************
* ITEM DAOs * * ITEM DAOs *
*************/ *************/
@ -132,8 +104,8 @@ public class JdbcHsqldbDAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tableName#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tableName#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), storedVO.getDbType(), storedVO.getTableName(), new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(),
sqlTypes.get("tablePrimaryValue") }); storedVO.getTableName(), sqlTypes.get("tablePrimaryValue") });
Object[] params = { storedVO.getValue() }; Object[] params = { storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
try { try {
@ -148,7 +120,8 @@ public class JdbcHsqldbDAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tableName#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tableName#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), storedVO.getDbType(), storedVO.getTableName(), "?" }); new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(),
storedVO.getTableName(), "?" });
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli());
Object[] params = { timestamp, storedVO.getValue() }; Object[] params = { timestamp, storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());

View File

@ -175,8 +175,7 @@ public class JdbcOracleDAO extends JdbcBaseDAO {
throw new JdbcSQLException(e); throw new JdbcSQLException(e);
} }
// We need to return the itemId, but Yank.insert does not retrieve the value from Oracle. So do an explicit // We need to return the itemId, but Yank.insert does not retrieve the value from Oracle. So do an explicit
// query // query for it.
// for it.
sql = StringUtilsExt.replaceArrayMerge(sqlGetItemTableID, new String[] { "#itemsManageTable#", "#colname#" }, sql = StringUtilsExt.replaceArrayMerge(sqlGetItemTableID, new String[] { "#itemsManageTable#", "#colname#" },
new String[] { vo.getItemsManageTable(), vo.getColname() }); new String[] { vo.getItemsManageTable(), vo.getColname() });
logger.debug("JDBC::doGetEntryIdInItemsTable sql={}", sql); logger.debug("JDBC::doGetEntryIdInItemsTable sql={}", sql);

View File

@ -60,28 +60,25 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
logger.debug("JDBC::initSqlQueries: '{}'", this.getClass().getSimpleName()); logger.debug("JDBC::initSqlQueries: '{}'", this.getClass().getSimpleName());
// System Information Functions: https://www.postgresql.org/docs/9.2/static/functions-info.html // System Information Functions: https://www.postgresql.org/docs/9.2/static/functions-info.html
sqlGetDB = "SELECT CURRENT_DATABASE()"; sqlGetDB = "SELECT CURRENT_DATABASE()";
sqlIfTableExists = "SELECT * FROM PG_TABLES WHERE TABLENAME='\"#searchTable#\"'"; sqlIfTableExists = "SELECT * FROM PG_TABLES WHERE TABLENAME='#searchTable#'";
sqlDropTable = "DROP TABLE \"#tableName#\""; sqlCreateItemsTableIfNot = "CREATE TABLE IF NOT EXISTS #itemsManageTable# (itemid SERIAL NOT NULL, #colname# #coltype# NOT NULL, CONSTRAINT #tablePrimaryKey# PRIMARY KEY (itemid))";
sqlCreateItemsTableIfNot = "CREATE TABLE IF NOT EXISTS \"#itemsManageTable#\" (itemid SERIAL NOT NULL, #colname# #coltype# NOT NULL, CONSTRAINT #itemsManageTable#_pkey PRIMARY KEY (itemid))"; sqlCreateNewEntryInItemsTable = "INSERT INTO items (itemname) SELECT itemname FROM #itemsManageTable# UNION VALUES ('#itemname#') EXCEPT SELECT itemname FROM items";
sqlCreateNewEntryInItemsTable = "INSERT INTO items (itemname) SELECT itemname FROM \"#itemsManageTable#\" UNION VALUES ('#itemname#') EXCEPT SELECT itemname FROM items";
sqlGetItemTables = """ sqlGetItemTables = """
SELECT table_name FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema=(SELECT table_schema \ SELECT table_name FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema=(SELECT table_schema \
FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_name='\"#itemsManageTable#\"') AND NOT table_name='\"#itemsManageTable#\"'\ FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_name='#itemsManageTable#') AND NOT table_name='#itemsManageTable#'\
"""; """;
// The PostgreSQL equivalent to MySQL columns.column_type is data_type (e.g. "timestamp with time zone") and // The PostgreSQL equivalent to MySQL columns.column_type is data_type (e.g. "timestamp with time zone") and
// udt_name which contains a shorter alias (e.g. "timestamptz"). We alias data_type as "column_type" and // udt_name which contains a shorter alias (e.g. "timestamptz"). We alias data_type as "column_type" and
// udt_name as "column_type_alias" to be compatible with the 'Column' class used in Yank.queryBeanList // udt_name as "column_type_alias" to be compatible with the 'Column' class used in Yank.queryBeanList
sqlGetTableColumnTypes = """ sqlGetTableColumnTypes = """
SELECT column_name, data_type as column_type, udt_name as column_type_alias, is_nullable FROM information_schema.columns \ SELECT column_name, data_type as column_type, udt_name as column_type_alias, is_nullable FROM information_schema.columns \
WHERE table_name='\"#tableName#\"' AND table_catalog='#jdbcUriDatabaseName#' AND table_schema=(SELECT table_schema FROM information_schema.tables WHERE table_type='BASE TABLE' \ WHERE table_name='#tableName#' AND table_catalog='#jdbcUriDatabaseName#' AND table_schema=(SELECT table_schema FROM information_schema.tables WHERE table_type='BASE TABLE' \
AND table_name='\"#itemsManageTable#\"')\ AND table_name='#itemsManageTable#')\
"""; """;
// NOTICE: on PostgreSql >= 9.5, sqlInsertItemValue query template is modified to do an "upsert" (overwrite // NOTICE: on PostgreSql >= 9.5, sqlInsertItemValue query template is modified to do an "upsert" (overwrite
// existing value). The version check and query change is performed at initAfterFirstDbConnection() // existing value). The version check and query change is performed at initAfterFirstDbConnection()
sqlInsertItemValue = "INSERT INTO \"#tableName#\" (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )"; sqlInsertItemValue = "INSERT INTO #tableName# (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )";
sqlCreateItemTable = "CREATE TABLE IF NOT EXISTS \"#tableName#\" (time #tablePrimaryKey# NOT NULL, value #dbType#, PRIMARY KEY(time))"; sqlAlterTableColumn = "ALTER TABLE #tableName# ALTER COLUMN #columnName# TYPE #columnType#";
sqlAlterTableColumn = "ALTER TABLE \"#tableName#\" ALTER COLUMN #columnName# TYPE #columnType#";
sqlGetRowCount = "SELECT COUNT(*) FROM \"#tableName#\"";
} }
@Override @Override
@ -95,7 +92,7 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
if (dbMeta.isDbVersionGreater(9, 4)) { if (dbMeta.isDbVersionGreater(9, 4)) {
logger.debug("JDBC::initAfterFirstDbConnection: Values with the same time will be upserted (Pg >= 9.5)"); logger.debug("JDBC::initAfterFirstDbConnection: Values with the same time will be upserted (Pg >= 9.5)");
sqlInsertItemValue = """ sqlInsertItemValue = """
INSERT INTO \"#tableName#\" (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )\ INSERT INTO #tableName# (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )\
ON CONFLICT (TIME) DO UPDATE SET VALUE=EXCLUDED.VALUE\ ON CONFLICT (TIME) DO UPDATE SET VALUE=EXCLUDED.VALUE\
"""; """;
} }
@ -145,8 +142,9 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
@Override @Override
public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException { public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot, String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot,
new String[] { "#itemsManageTable#", "#colname#", "#coltype#", "#itemsManageTable#" }, new String[] { "#itemsManageTable#", "#colname#", "#coltype#", "#tablePrimaryKey#" },
new String[] { vo.getItemsManageTable(), vo.getColname(), vo.getColtype(), vo.getItemsManageTable() }); new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getColname(), vo.getColtype(),
vo.getItemsManageTable() + "_pkey" });
logger.debug("JDBC::doCreateItemsTableIfNot sql={}", sql); logger.debug("JDBC::doCreateItemsTableIfNot sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -156,25 +154,12 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
return vo; return vo;
} }
@Override
public Long doCreateNewEntryInItemsTable(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateNewEntryInItemsTable,
new String[] { "#itemsManageTable#", "#itemname#" },
new String[] { vo.getItemsManageTable(), vo.getItemName() });
logger.debug("JDBC::doCreateNewEntryInItemsTable sql={}", sql);
try {
return Yank.insert(sql, null);
} catch (YankSQLException e) {
throw new JdbcSQLException(e);
}
}
@Override @Override
public List<ItemsVO> doGetItemTables(ItemsVO vo) throws JdbcSQLException { public List<ItemsVO> doGetItemTables(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(this.sqlGetItemTables, String sql = StringUtilsExt.replaceArrayMerge(sqlGetItemTables,
new String[] { "#itemsManageTable#", "#itemsManageTable#" }, new String[] { "#itemsManageTable#", "#itemsManageTable#" },
new String[] { vo.getItemsManageTable(), vo.getItemsManageTable() }); new String[] { vo.getItemsManageTable(), vo.getItemsManageTable() });
this.logger.debug("JDBC::doGetItemTables sql={}", sql); logger.debug("JDBC::doGetItemTables sql={}", sql);
try { try {
return Yank.queryBeanList(sql, ItemsVO.class, null); return Yank.queryBeanList(sql, ItemsVO.class, null);
} catch (YankSQLException e) { } catch (YankSQLException e) {
@ -210,15 +195,16 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
throws JdbcSQLException { throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlAlterTableColumn, String sql = StringUtilsExt.replaceArrayMerge(sqlAlterTableColumn,
new String[] { "#tableName#", "#columnName#", "#columnType#" }, new String[] { "#tableName#", "#columnName#", "#columnType#" },
new String[] { tableName, columnName, columnType }); new String[] { formattedIdentifier(tableName), columnName, columnType });
logger.info("JDBC::doAlterTableColumn sql={}", sql); logger.debug("JDBC::doAlterTableColumn sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
if (!nullable) { if (!nullable) {
String sql2 = StringUtilsExt.replaceArrayMerge( String sql2 = StringUtilsExt.replaceArrayMerge(
"ALTER TABLE \"#tableName#\" ALTER COLUMN #columnName# SET NOT NULL", "ALTER TABLE #tableName# ALTER COLUMN #columnName# SET NOT NULL",
new String[] { "#tableName#", "#columnName#" }, new String[] { tableName, columnName }); new String[] { "#tableName#", "#columnName#" },
logger.info("JDBC::doAlterTableColumn sql={}", sql2); new String[] { formattedIdentifier(tableName), columnName });
logger.debug("JDBC::doAlterTableColumn sql={}", sql2);
Yank.execute(sql2, null); Yank.execute(sql2, null);
} }
} catch (YankSQLException e) { } catch (YankSQLException e) {
@ -231,7 +217,8 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), storedVO.getDbType(), sqlTypes.get("tablePrimaryValue") }); new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(),
sqlTypes.get("tablePrimaryValue") });
Object[] params = { storedVO.getValue() }; Object[] params = { storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
try { try {
@ -246,7 +233,7 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), storedVO.getDbType(), "?" }); new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), "?" });
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli());
Object[] params = { timestamp, storedVO.getValue() }; Object[] params = { timestamp, storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());
@ -287,8 +274,9 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
+ filter.getPageSize(); + filter.getPageSize();
} }
String queryString = "NUMBERITEM".equalsIgnoreCase(simpleName) && numberDecimalcount > -1 String queryString = "NUMBERITEM".equalsIgnoreCase(simpleName) && numberDecimalcount > -1
? "SELECT time, ROUND(CAST (value AS numeric)," + numberDecimalcount + ") FROM " + table ? "SELECT time, ROUND(CAST (value AS numeric)," + numberDecimalcount + ") FROM "
: "SELECT time, value FROM " + table; + formattedIdentifier(table)
: "SELECT time, value FROM " + formattedIdentifier(table);
if (!filterString.isEmpty()) { if (!filterString.isEmpty()) {
queryString += filterString; queryString += filterString;
} }
@ -299,6 +287,10 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
/***************** /*****************
* H E L P E R S * * H E L P E R S *
*****************/ *****************/
@Override
protected String formattedIdentifier(String identifier) {
return "\"" + identifier + "\"";
}
/****************************** /******************************
* public Getters and Setters * * public Getters and Setters *

View File

@ -96,7 +96,7 @@ public class JdbcSqliteDAO extends JdbcBaseDAO {
public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException { public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException {
String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot, String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot,
new String[] { "#itemsManageTable#", "#colname#", "#coltype#" }, new String[] { "#itemsManageTable#", "#colname#", "#coltype#" },
new String[] { vo.getItemsManageTable(), vo.getColname(), vo.getColtype() }); new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getColname(), vo.getColtype() });
logger.debug("JDBC::doCreateItemsTableIfNot sql={}", sql); logger.debug("JDBC::doCreateItemsTableIfNot sql={}", sql);
try { try {
Yank.execute(sql, null); Yank.execute(sql, null);
@ -114,7 +114,8 @@ public class JdbcSqliteDAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), storedVO.getDbType(), sqlTypes.get("tablePrimaryValue") }); new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(),
sqlTypes.get("tablePrimaryValue") });
Object[] params = { storedVO.getValue() }; Object[] params = { storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
try { try {
@ -129,7 +130,7 @@ public class JdbcSqliteDAO extends JdbcBaseDAO {
ItemVO storedVO = storeItemValueProvider(item, itemState, vo); ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue, String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" }, new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
new String[] { storedVO.getTableName(), storedVO.getDbType(), "?" }); new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(), "?" });
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli()); java.sql.Timestamp timestamp = new java.sql.Timestamp(date.toInstant().toEpochMilli());
Object[] params = { timestamp, storedVO.getValue() }; Object[] params = { timestamp, storedVO.getValue() };
logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue()); logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());

View File

@ -36,8 +36,8 @@ import org.slf4j.LoggerFactory;
public class JdbcTimescaledbDAO extends JdbcPostgresqlDAO { public class JdbcTimescaledbDAO extends JdbcPostgresqlDAO {
private final Logger logger = LoggerFactory.getLogger(JdbcTimescaledbDAO.class); private final Logger logger = LoggerFactory.getLogger(JdbcTimescaledbDAO.class);
private final String sqlCreateHypertable = "SELECT created FROM create_hypertable('\"#tableName#\"', 'time')"; private final String sqlCreateHypertable = "SELECT created FROM create_hypertable('#tableName#', 'time')";
private final String sqlGetItemTables = "SELECT hypertable_name as table_name FROM timescaledb_information.hypertables WHERE hypertable_name != '\"#itemsManageTable#\"'"; private final String sqlGetItemTables = "SELECT hypertable_name AS table_name FROM timescaledb_information.hypertables WHERE hypertable_name != '#itemsManageTable#'";
@Override @Override
public Properties getConnectionProperties() { public Properties getConnectionProperties() {
@ -57,7 +57,7 @@ public class JdbcTimescaledbDAO extends JdbcPostgresqlDAO {
public void doCreateItemTable(ItemVO vo) throws JdbcSQLException { public void doCreateItemTable(ItemVO vo) throws JdbcSQLException {
super.doCreateItemTable(vo); super.doCreateItemTable(vo);
String sql = StringUtilsExt.replaceArrayMerge(this.sqlCreateHypertable, new String[] { "#tableName#" }, String sql = StringUtilsExt.replaceArrayMerge(this.sqlCreateHypertable, new String[] { "#tableName#" },
new String[] { vo.getTableName() }); new String[] { formattedIdentifier(vo.getTableName()) });
this.logger.debug("JDBC::doCreateItemTable sql={}", sql); this.logger.debug("JDBC::doCreateItemTable sql={}", sql);
try { try {
Yank.queryScalar(sql, Boolean.class, null); Yank.queryScalar(sql, Boolean.class, null);