diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcPostgresqlDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcPostgresqlDAO.java index 6e05a7b77f2..577a93dfe17 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcPostgresqlDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcPostgresqlDAO.java @@ -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); diff --git a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcTimescaledbDAO.java b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcTimescaledbDAO.java index 28514a412b0..6c6bbba7ee1 100644 --- a/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcTimescaledbDAO.java +++ b/bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcTimescaledbDAO.java @@ -12,12 +12,14 @@ */ 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 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); + } + } }