]> git.basschouten.com Git - openhab-addons.git/commitdiff
[jdbc] Fix case-sensitive table names for PostgreSQL (#17597)
authorJacob Laursen <jacob-github@vindvejr.dk>
Mon, 21 Oct 2024 21:48:59 +0000 (23:48 +0200)
committerGitHub <noreply@github.com>
Mon, 21 Oct 2024 21:48:59 +0000 (23:48 +0200)
* Fix case-sensitive table names for PostgreSQL

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
bundles/org.openhab.persistence.jdbc/README.md
bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcBaseDAO.java
bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcDerbyDAO.java
bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcH2DAO.java
bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcHsqldbDAO.java
bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcOracleDAO.java
bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcPostgresqlDAO.java
bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcSqliteDAO.java
bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcTimescaledbDAO.java

index d0830ff256a322b4362d64c23fe41b56f9293ee6..04b0f82a43b93c42785ac3f153767eafe0838671 100644 (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
 
-```
+```ini
 org.openhab.core.persistence:default=jdbc
 ```
 
@@ -89,7 +89,7 @@ in the file `services/runtime.cfg`.
 
 services/jdbc.cfg
 
-```
+```ini
 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:
 
-```
+```ini
 url=jdbc:oracle:thin:@dbname?TNS_ADMIN=./dbname_tns_admin_folder
 user=openhab
 password=openhab_password
@@ -147,7 +147,7 @@ Here is an example of a configuration for a MySQL database named `testMysql` wit
 
 services/jdbc.cfg
 
-```
+```ini
 url=jdbc:mysql://192.168.0.1:3306/testMysql
 user=test
 password=test
index f524c6fc50a817a740127a92a8b3da4ea607381d..35179d1eccde70c700ef3d8229a123defcd2f316 100644 (file)
@@ -296,7 +296,7 @@ public class JdbcBaseDAO {
     public Long doCreateNewEntryInItemsTable(ItemsVO vo) throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlCreateNewEntryInItemsTable,
                 new String[] { "#itemsManageTable#", "#itemname#" },
-                new String[] { vo.getItemsManageTable(), vo.getItemName() });
+                new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getItemName() });
         logger.debug("JDBC::doCreateNewEntryInItemsTable sql={}", sql);
         try {
             return Yank.insert(sql, null);
@@ -308,7 +308,7 @@ public class JdbcBaseDAO {
     public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot,
                 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);
         try {
             Yank.execute(sql, null);
@@ -320,7 +320,7 @@ public class JdbcBaseDAO {
 
     public ItemsVO doDropItemsTableIfExists(ItemsVO vo) throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlDropItemsTableIfExists, new String[] { "#itemsManageTable#" },
-                new String[] { vo.getItemsManageTable() });
+                new String[] { formattedIdentifier(vo.getItemsManageTable()) });
         logger.debug("JDBC::doDropItemsTableIfExists sql={}", sql);
         try {
             Yank.execute(sql, null);
@@ -332,7 +332,7 @@ public class JdbcBaseDAO {
 
     public void doDropTable(String tableName) throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlDropTable, new String[] { "#tableName#" },
-                new String[] { tableName });
+                new String[] { formattedIdentifier(tableName) });
         logger.debug("JDBC::doDropTable sql={}", sql);
         try {
             Yank.execute(sql, null);
@@ -344,7 +344,7 @@ public class JdbcBaseDAO {
     public void doDeleteItemsEntry(ItemsVO vo) throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlDeleteItemsEntry,
                 new String[] { "#itemsManageTable#", "#itemname#" },
-                new String[] { vo.getItemsManageTable(), vo.getItemName() });
+                new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getItemName() });
         logger.debug("JDBC::doDeleteItemsEntry sql={}", sql);
         try {
             Yank.execute(sql, null);
@@ -355,7 +355,7 @@ public class JdbcBaseDAO {
 
     public List<ItemsVO> doGetItemIDTableNames(ItemsVO vo) throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlGetItemIDTableNames, new String[] { "#itemsManageTable#" },
-                new String[] { vo.getItemsManageTable() });
+                new String[] { formattedIdentifier(vo.getItemsManageTable()) });
         logger.debug("JDBC::doGetItemIDTableNames sql={}", sql);
         try {
             return Yank.queryBeanList(sql, ItemsVO.class, null);
@@ -405,8 +405,8 @@ public class JdbcBaseDAO {
 
     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") });
+                new String[] { "#tableName#", "#dbType#", "#tablePrimaryKey#" }, new String[] {
+                        formattedIdentifier(vo.getTableName()), vo.getDbType(), sqlTypes.get("tablePrimaryKey") });
         logger.debug("JDBC::doCreateItemTable sql={}", sql);
         try {
             Yank.execute(sql, null);
@@ -418,8 +418,8 @@ public class JdbcBaseDAO {
     public void doAlterTableColumn(String tableName, String columnName, String columnType, boolean nullable)
             throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlAlterTableColumn,
-                new String[] { "#tableName#", "#columnName#", "#columnType#" },
-                new String[] { tableName, columnName, nullable ? columnType : columnType + " NOT NULL" });
+                new String[] { "#tableName#", "#columnName#", "#columnType#" }, new String[] {
+                        formattedIdentifier(tableName), columnName, nullable ? columnType : columnType + " NOT NULL" });
         logger.debug("JDBC::doAlterTableColumn sql={}", sql);
         try {
             Yank.execute(sql, null);
@@ -432,7 +432,7 @@ public class JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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() };
         logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
         try {
@@ -445,7 +445,8 @@ public class JdbcBaseDAO {
     public void doStoreItemValue(Item item, State itemState, ItemVO vo, ZonedDateTime date) throws JdbcSQLException {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         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());
         Object[] params = { timestamp, storedVO.getValue(), 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 {
         final String sql = StringUtilsExt.replaceArrayMerge(sqlGetRowCount, new String[] { "#tableName#" },
-                new String[] { tableName });
+                new String[] { formattedIdentifier(tableName) });
         logger.debug("JDBC::doGetRowCount sql={}", sql);
         try {
             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
         // rounding HALF UP
         String queryString = "NUMBERITEM".equalsIgnoreCase(simpleName) && numberDecimalcount > -1
-                ? "SELECT time, ROUND(value," + numberDecimalcount + ") FROM " + table
-                : "SELECT time, value FROM " + table;
+                ? "SELECT time, ROUND(value," + numberDecimalcount + ") FROM " + formattedIdentifier(table)
+                : "SELECT time, value FROM " + formattedIdentifier(table);
         if (!filterString.isEmpty()) {
             queryString += filterString;
         }
@@ -532,8 +533,8 @@ public class JdbcBaseDAO {
         logger.debug("JDBC::histItemFilterDeleteProvider filter = {}, table = {}", filter, table);
 
         String filterString = resolveTimeFilter(filter, timeZone);
-        String deleteString = filterString.isEmpty() ? "TRUNCATE TABLE " + table
-                : "DELETE FROM " + table + filterString;
+        String deleteString = filterString.isEmpty() ? "TRUNCATE TABLE " + formattedIdentifier(table)
+                : "DELETE FROM " + formattedIdentifier(table) + filterString;
         logger.debug("JDBC::delete deleteString = {}", deleteString);
         return deleteString;
     }
@@ -554,7 +555,12 @@ public class JdbcBaseDAO {
     }
 
     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);
         return queryString;
     }
@@ -757,7 +763,11 @@ public class JdbcBaseDAO {
         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;
         String def = "STRINGITEM";
         if (i instanceof GroupItem groupItem) {
index d1be0bee42ff27172dfbcaabc5213830ffcdeb84..95b294430f4df19ea9bd6a1c4fb9c44cee9256ca 100644 (file)
@@ -14,26 +14,18 @@ package org.openhab.persistence.jdbc.internal.db;
 
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
-import java.util.List;
 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.Nullable;
 import org.knowm.yank.Yank;
 import org.knowm.yank.exceptions.YankSQLException;
 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.Ordering;
-import org.openhab.core.persistence.HistoricItem;
 import org.openhab.core.types.State;
 import org.openhab.persistence.jdbc.internal.dto.ItemVO;
 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.utils.StringUtilsExt;
 import org.slf4j.Logger;
@@ -121,7 +113,7 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
     @Override
     public boolean doIfTableExists(ItemsVO vo) throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlIfTableExists, new String[] { "#searchTable#" },
-                new String[] { vo.getItemsManageTable().toUpperCase() });
+                new String[] { formattedIdentifier(vo.getItemsManageTable()) });
         logger.debug("JDBC::doIfTableExists sql={}", sql);
         try {
             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
     public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException {
         boolean tableExists = doIfTableExists(vo);
         if (!tableExists) {
             String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot,
                     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);
             try {
                 Yank.execute(sql, null);
@@ -166,24 +145,12 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
     /*************
      * 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
     public void doStoreItemValue(Item item, State itemState, ItemVO vo) throws JdbcSQLException {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 new String[] { "#tableName#", "#dbType#", "#tablePrimaryValue#" },
-                new String[] { storedVO.getTableName().toUpperCase(), storedVO.getDbType(),
+                new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(),
                         sqlTypes.get("tablePrimaryValue") });
         Object[] params = { 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);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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());
         Object[] params = { 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 *
      ****************************/
@@ -280,7 +227,7 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
             queryString += "5 AS DECIMAL(31," + numberDecimalcount + "))"; // 31 is DECIMAL max precision
                                                                            // https://db.apache.org/derby/docs/10.0/manuals/develop/develop151.html
         } else {
-            queryString += " value FROM " + table.toUpperCase();
+            queryString += " value FROM " + formattedIdentifier(table);
         }
 
         if (!filterString.isEmpty()) {
@@ -293,6 +240,10 @@ public class JdbcDerbyDAO extends JdbcBaseDAO {
     /*****************
      * H E L P E R S *
      *****************/
+    @Override
+    protected String formattedIdentifier(String identifier) {
+        return identifier.toUpperCase();
+    }
 
     /******************************
      * public Getters and Setters *
index 51c7d3567eda82e361518c72736dbbcb49848518..409b2895b615f96fd530328342cd91eb8ff13076 100644 (file)
@@ -85,7 +85,8 @@ public class JdbcH2DAO extends JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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() };
         logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
         try {
@@ -100,7 +101,7 @@ public class JdbcH2DAO extends JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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());
         Object[] params = { timestamp, storedVO.getValue() };
         logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());
index 9caa2fcc2ffce024351e47e2857233b7eccd145c..150a0cede4f79c1f8a0740ad8d8ed9edf4054aa7 100644 (file)
@@ -21,7 +21,6 @@ import org.knowm.yank.exceptions.YankSQLException;
 import org.openhab.core.items.Item;
 import org.openhab.core.types.State;
 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.utils.StringUtilsExt;
 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 *
      *************/
@@ -132,8 +104,8 @@ public class JdbcHsqldbDAO extends JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 new String[] { "#tableName#", "#dbType#", "#tableName#", "#tablePrimaryValue#" },
-                new String[] { storedVO.getTableName(), storedVO.getDbType(), storedVO.getTableName(),
-                        sqlTypes.get("tablePrimaryValue") });
+                new String[] { formattedIdentifier(storedVO.getTableName()), storedVO.getDbType(),
+                        storedVO.getTableName(), sqlTypes.get("tablePrimaryValue") });
         Object[] params = { storedVO.getValue() };
         logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
         try {
@@ -148,7 +120,8 @@ public class JdbcHsqldbDAO extends JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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());
         Object[] params = { timestamp, storedVO.getValue() };
         logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());
index 63db39eadc30374f52700dfe18e62eb1a52f0bb9..4925726ee13b201db833f24102151672b7ff5392 100644 (file)
@@ -175,8 +175,7 @@ public class JdbcOracleDAO extends JdbcBaseDAO {
             throw new JdbcSQLException(e);
         }
         // We need to return the itemId, but Yank.insert does not retrieve the value from Oracle. So do an explicit
-        // query
-        // for it.
+        // query for it.
         sql = StringUtilsExt.replaceArrayMerge(sqlGetItemTableID, new String[] { "#itemsManageTable#", "#colname#" },
                 new String[] { vo.getItemsManageTable(), vo.getColname() });
         logger.debug("JDBC::doGetEntryIdInItemsTable sql={}", sql);
index 577a93dfe17580bc7ae3d1f5dc1b2ae34bb5ccd3..5235fc90e191f7a59977e62bd3d400c2d0629378 100644 (file)
@@ -60,28 +60,25 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
         logger.debug("JDBC::initSqlQueries: '{}'", this.getClass().getSimpleName());
         // System Information Functions: https://www.postgresql.org/docs/9.2/static/functions-info.html
         sqlGetDB = "SELECT CURRENT_DATABASE()";
-        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 #itemsManageTable#_pkey PRIMARY KEY (itemid))";
-        sqlCreateNewEntryInItemsTable = "INSERT INTO items (itemname) SELECT itemname FROM \"#itemsManageTable#\"  UNION VALUES ('#itemname#') EXCEPT SELECT itemname FROM items";
+        sqlIfTableExists = "SELECT * FROM PG_TABLES WHERE TABLENAME='#searchTable#'";
+        sqlCreateItemsTableIfNot = "CREATE TABLE IF NOT EXISTS #itemsManageTable# (itemid SERIAL NOT NULL, #colname# #coltype# NOT NULL, CONSTRAINT #tablePrimaryKey# PRIMARY KEY (itemid))";
+        sqlCreateNewEntryInItemsTable = "INSERT INTO items (itemname) SELECT itemname FROM #itemsManageTable# UNION VALUES ('#itemname#') EXCEPT SELECT itemname FROM items";
         sqlGetItemTables = """
                 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
         // 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
         sqlGetTableColumnTypes = """
                 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' \
-                AND table_name='\"#itemsManageTable#\"')\
+                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#')\
                 """;
         // 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()
-        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#";
-        sqlGetRowCount = "SELECT COUNT(*) FROM \"#tableName#\"";
+        sqlInsertItemValue = "INSERT INTO #tableName# (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )";
+        sqlAlterTableColumn = "ALTER TABLE #tableName# ALTER COLUMN #columnName# TYPE #columnType#";
     }
 
     @Override
@@ -95,7 +92,7 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
         if (dbMeta.isDbVersionGreater(9, 4)) {
             logger.debug("JDBC::initAfterFirstDbConnection: Values with the same time will be upserted (Pg >= 9.5)");
             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\
                     """;
         }
@@ -145,8 +142,9 @@ public class JdbcPostgresqlDAO 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() });
+                new String[] { "#itemsManageTable#", "#colname#", "#coltype#", "#tablePrimaryKey#" },
+                new String[] { formattedIdentifier(vo.getItemsManageTable()), vo.getColname(), vo.getColtype(),
+                        vo.getItemsManageTable() + "_pkey" });
         logger.debug("JDBC::doCreateItemsTableIfNot sql={}", sql);
         try {
             Yank.execute(sql, null);
@@ -156,25 +154,12 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
         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
     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[] { vo.getItemsManageTable(), vo.getItemsManageTable() });
-        this.logger.debug("JDBC::doGetItemTables sql={}", sql);
+        logger.debug("JDBC::doGetItemTables sql={}", sql);
         try {
             return Yank.queryBeanList(sql, ItemsVO.class, null);
         } catch (YankSQLException e) {
@@ -210,15 +195,16 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
             throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlAlterTableColumn,
                 new String[] { "#tableName#", "#columnName#", "#columnType#" },
-                new String[] { tableName, columnName, columnType });
-        logger.info("JDBC::doAlterTableColumn sql={}", sql);
+                new String[] { formattedIdentifier(tableName), columnName, columnType });
+        logger.debug("JDBC::doAlterTableColumn sql={}", sql);
         try {
             Yank.execute(sql, null);
             if (!nullable) {
                 String sql2 = StringUtilsExt.replaceArrayMerge(
-                        "ALTER TABLE \"#tableName#\" ALTER COLUMN #columnName# SET NOT NULL",
-                        new String[] { "#tableName#", "#columnName#" }, new String[] { tableName, columnName });
-                logger.info("JDBC::doAlterTableColumn sql={}", sql2);
+                        "ALTER TABLE #tableName# ALTER COLUMN #columnName# SET NOT NULL",
+                        new String[] { "#tableName#", "#columnName#" },
+                        new String[] { formattedIdentifier(tableName), columnName });
+                logger.debug("JDBC::doAlterTableColumn sql={}", sql2);
                 Yank.execute(sql2, null);
             }
         } catch (YankSQLException e) {
@@ -231,7 +217,8 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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() };
         logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
         try {
@@ -246,7 +233,7 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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());
         Object[] params = { 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();
         }
         String queryString = "NUMBERITEM".equalsIgnoreCase(simpleName) && numberDecimalcount > -1
-                ? "SELECT time, ROUND(CAST (value AS numeric)," + numberDecimalcount + ") FROM " + table
-                : "SELECT time, value FROM " + table;
+                ? "SELECT time, ROUND(CAST (value AS numeric)," + numberDecimalcount + ") FROM "
+                        + formattedIdentifier(table)
+                : "SELECT time, value FROM " + formattedIdentifier(table);
         if (!filterString.isEmpty()) {
             queryString += filterString;
         }
@@ -299,6 +287,10 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
     /*****************
      * H E L P E R S *
      *****************/
+    @Override
+    protected String formattedIdentifier(String identifier) {
+        return "\"" + identifier + "\"";
+    }
 
     /******************************
      * public Getters and Setters *
index c5bc9d1f3240cc25a67b25e7115bdb349bff5299..95e4495cb4fa92cc805f3568c50a0031a743cc69 100644 (file)
@@ -96,7 +96,7 @@ public class JdbcSqliteDAO extends JdbcBaseDAO {
     public ItemsVO doCreateItemsTableIfNot(ItemsVO vo) throws JdbcSQLException {
         String sql = StringUtilsExt.replaceArrayMerge(sqlCreateItemsTableIfNot,
                 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);
         try {
             Yank.execute(sql, null);
@@ -114,7 +114,8 @@ public class JdbcSqliteDAO extends JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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() };
         logger.debug("JDBC::doStoreItemValue sql={} value='{}'", sql, storedVO.getValue());
         try {
@@ -129,7 +130,7 @@ public class JdbcSqliteDAO extends JdbcBaseDAO {
         ItemVO storedVO = storeItemValueProvider(item, itemState, vo);
         String sql = StringUtilsExt.replaceArrayMerge(sqlInsertItemValue,
                 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());
         Object[] params = { timestamp, storedVO.getValue() };
         logger.debug("JDBC::doStoreItemValue sql={} timestamp={} value='{}'", sql, timestamp, storedVO.getValue());
index 6c6bbba7ee1aa188b39f767b50e2cc2a8428549b..ba7d89a5f58a2ce7607d37acbad32c76e242ed22 100644 (file)
@@ -36,8 +36,8 @@ import org.slf4j.LoggerFactory;
 public class JdbcTimescaledbDAO extends JdbcPostgresqlDAO {
     private final Logger logger = LoggerFactory.getLogger(JdbcTimescaledbDAO.class);
 
-    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 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#'";
 
     @Override
     public Properties getConnectionProperties() {
@@ -57,7 +57,7 @@ public class JdbcTimescaledbDAO extends JdbcPostgresqlDAO {
     public void doCreateItemTable(ItemVO vo) throws JdbcSQLException {
         super.doCreateItemTable(vo);
         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);
         try {
             Yank.queryScalar(sql, Boolean.class, null);