]> git.basschouten.com Git - openhab-addons.git/commitdiff
[jdbc] Fix `tableCaseSensitiveItemNames` for PostgreSQL/TimescaleDB (#17587)
authorJonathanvdGHU <114060262+JonathanvdGHU@users.noreply.github.com>
Sat, 19 Oct 2024 21:07:16 +0000 (23:07 +0200)
committerGitHub <noreply@github.com>
Sat, 19 Oct 2024 21:07:16 +0000 (23:07 +0200)
Signed-off-by: Jonathan van de Giessen <jonathan.vandegiessen@student.hu.nl>
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/JdbcTimescaledbDAO.java

index 6e05a7b77f29bd2f2a91f5e21600174e7c28660f..577a93dfe17580bc7ae3d1f5dc1b2ae34bb5ccd3 100644 (file)
@@ -60,25 +60,28 @@ 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#'";
-        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#\"'";
+        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";
         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#) )";
-        sqlAlterTableColumn = "ALTER TABLE #tableName# ALTER COLUMN #columnName# TYPE #columnType#";
+        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#\"";
     }
 
     @Override
@@ -92,7 +95,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\
                     """;
         }
@@ -213,7 +216,7 @@ public class JdbcPostgresqlDAO extends JdbcBaseDAO {
             Yank.execute(sql, null);
             if (!nullable) {
                 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 });
                 logger.info("JDBC::doAlterTableColumn sql={}", sql2);
                 Yank.execute(sql2, null);
index 28514a412b0dc5e7a28e9ac3c65515ee2787d837..6c6bbba7ee1aa188b39f767b50e2cc2a8428549b 100644 (file)
  */
 package org.openhab.persistence.jdbc.internal.db;
 
+import java.util.List;
 import java.util.Properties;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.knowm.yank.Yank;
 import org.knowm.yank.exceptions.YankSQLException;
 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;
@@ -34,7 +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 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() {
@@ -46,6 +49,10 @@ public class JdbcTimescaledbDAO extends JdbcPostgresqlDAO {
         return properties;
     }
 
+    /*************
+     * ITEM DAOs *
+     *************/
+
     @Override
     public void doCreateItemTable(ItemVO vo) throws JdbcSQLException {
         super.doCreateItemTable(vo);
@@ -58,4 +65,16 @@ public class JdbcTimescaledbDAO extends JdbcPostgresqlDAO {
             throw new JdbcSQLException(e);
         }
     }
+
+    @Override
+    public List<ItemsVO> doGetItemTables(ItemsVO vo) throws JdbcSQLException {
+        String sql = StringUtilsExt.replaceArrayMerge(sqlGetItemTables, new String[] { "#itemsManageTable#" },
+                new String[] { vo.getItemsManageTable() });
+        this.logger.debug("JDBC::doGetItemTables sql={}", sql);
+        try {
+            return Yank.queryBeanList(sql, ItemsVO.class, null);
+        } catch (YankSQLException e) {
+            throw new JdbcSQLException(e);
+        }
+    }
 }