Skip to content

Commit e9a6cb6

Browse files
authoredOct 19, 2024··
[jdbc] Fix tableCaseSensitiveItemNames for PostgreSQL/TimescaleDB (openhab#17587)
Signed-off-by: Jonathan van de Giessen <jonathan.vandegiessen@student.hu.nl>
1 parent 170444b commit e9a6cb6

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed
 

‎bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcPostgresqlDAO.java

+13-10
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,28 @@ private void initSqlQueries() {
6060
logger.debug("JDBC::initSqlQueries: '{}'", this.getClass().getSimpleName());
6161
// System Information Functions: https://www.postgresql.org/docs/9.2/static/functions-info.html
6262
sqlGetDB = "SELECT CURRENT_DATABASE()";
63-
sqlIfTableExists = "SELECT * FROM PG_TABLES WHERE TABLENAME='#searchTable#'";
64-
sqlCreateItemsTableIfNot = "CREATE TABLE IF NOT EXISTS #itemsManageTable# (itemid SERIAL NOT NULL, #colname# #coltype# NOT NULL, CONSTRAINT #itemsManageTable#_pkey PRIMARY KEY (itemid))";
65-
sqlCreateNewEntryInItemsTable = "INSERT INTO items (itemname) SELECT itemname FROM #itemsManageTable# UNION VALUES ('#itemname#') EXCEPT SELECT itemname FROM items";
63+
sqlIfTableExists = "SELECT * FROM PG_TABLES WHERE TABLENAME='\"#searchTable#\"'";
64+
sqlDropTable = "DROP TABLE \"#tableName#\"";
65+
sqlCreateItemsTableIfNot = "CREATE TABLE IF NOT EXISTS \"#itemsManageTable#\" (itemid SERIAL NOT NULL, #colname# #coltype# NOT NULL, CONSTRAINT #itemsManageTable#_pkey PRIMARY KEY (itemid))";
66+
sqlCreateNewEntryInItemsTable = "INSERT INTO items (itemname) SELECT itemname FROM \"#itemsManageTable#\" UNION VALUES ('#itemname#') EXCEPT SELECT itemname FROM items";
6667
sqlGetItemTables = """
6768
SELECT table_name FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema=(SELECT table_schema \
68-
FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_name='#itemsManageTable#') AND NOT table_name='#itemsManageTable#'\
69+
FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_name='\"#itemsManageTable#\"') AND NOT table_name='\"#itemsManageTable#\"'\
6970
""";
7071
// The PostgreSQL equivalent to MySQL columns.column_type is data_type (e.g. "timestamp with time zone") and
7172
// udt_name which contains a shorter alias (e.g. "timestamptz"). We alias data_type as "column_type" and
7273
// udt_name as "column_type_alias" to be compatible with the 'Column' class used in Yank.queryBeanList
7374
sqlGetTableColumnTypes = """
7475
SELECT column_name, data_type as column_type, udt_name as column_type_alias, is_nullable FROM information_schema.columns \
75-
WHERE table_name='#tableName#' AND table_catalog='#jdbcUriDatabaseName#' AND table_schema=(SELECT table_schema FROM information_schema.tables WHERE table_type='BASE TABLE' \
76-
AND table_name='#itemsManageTable#')\
76+
WHERE table_name='\"#tableName#\"' AND table_catalog='#jdbcUriDatabaseName#' AND table_schema=(SELECT table_schema FROM information_schema.tables WHERE table_type='BASE TABLE' \
77+
AND table_name='\"#itemsManageTable#\"')\
7778
""";
7879
// NOTICE: on PostgreSql >= 9.5, sqlInsertItemValue query template is modified to do an "upsert" (overwrite
7980
// existing value). The version check and query change is performed at initAfterFirstDbConnection()
80-
sqlInsertItemValue = "INSERT INTO #tableName# (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )";
81-
sqlAlterTableColumn = "ALTER TABLE #tableName# ALTER COLUMN #columnName# TYPE #columnType#";
81+
sqlInsertItemValue = "INSERT INTO \"#tableName#\" (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )";
82+
sqlCreateItemTable = "CREATE TABLE IF NOT EXISTS \"#tableName#\" (time #tablePrimaryKey# NOT NULL, value #dbType#, PRIMARY KEY(time))";
83+
sqlAlterTableColumn = "ALTER TABLE \"#tableName#\" ALTER COLUMN #columnName# TYPE #columnType#";
84+
sqlGetRowCount = "SELECT COUNT(*) FROM \"#tableName#\"";
8285
}
8386

8487
@Override
@@ -92,7 +95,7 @@ public void initAfterFirstDbConnection() {
9295
if (dbMeta.isDbVersionGreater(9, 4)) {
9396
logger.debug("JDBC::initAfterFirstDbConnection: Values with the same time will be upserted (Pg >= 9.5)");
9497
sqlInsertItemValue = """
95-
INSERT INTO #tableName# (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )\
98+
INSERT INTO \"#tableName#\" (TIME, VALUE) VALUES( #tablePrimaryValue#, CAST( ? as #dbType#) )\
9699
ON CONFLICT (TIME) DO UPDATE SET VALUE=EXCLUDED.VALUE\
97100
""";
98101
}
@@ -213,7 +216,7 @@ public void doAlterTableColumn(String tableName, String columnName, String colum
213216
Yank.execute(sql, null);
214217
if (!nullable) {
215218
String sql2 = StringUtilsExt.replaceArrayMerge(
216-
"ALTER TABLE #tableName# ALTER COLUMN #columnName# SET NOT NULL",
219+
"ALTER TABLE \"#tableName#\" ALTER COLUMN #columnName# SET NOT NULL",
217220
new String[] { "#tableName#", "#columnName#" }, new String[] { tableName, columnName });
218221
logger.info("JDBC::doAlterTableColumn sql={}", sql2);
219222
Yank.execute(sql2, null);

‎bundles/org.openhab.persistence.jdbc/src/main/java/org/openhab/persistence/jdbc/internal/db/JdbcTimescaledbDAO.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
*/
1313
package org.openhab.persistence.jdbc.internal.db;
1414

15+
import java.util.List;
1516
import java.util.Properties;
1617

1718
import org.eclipse.jdt.annotation.NonNullByDefault;
1819
import org.knowm.yank.Yank;
1920
import org.knowm.yank.exceptions.YankSQLException;
2021
import org.openhab.persistence.jdbc.internal.dto.ItemVO;
22+
import org.openhab.persistence.jdbc.internal.dto.ItemsVO;
2123
import org.openhab.persistence.jdbc.internal.exceptions.JdbcSQLException;
2224
import org.openhab.persistence.jdbc.internal.utils.StringUtilsExt;
2325
import org.slf4j.Logger;
@@ -34,7 +36,8 @@
3436
public class JdbcTimescaledbDAO extends JdbcPostgresqlDAO {
3537
private final Logger logger = LoggerFactory.getLogger(JdbcTimescaledbDAO.class);
3638

37-
private final String sqlCreateHypertable = "SELECT created from create_hypertable('#tableName#', 'time')";
39+
private final String sqlCreateHypertable = "SELECT created FROM create_hypertable('\"#tableName#\"', 'time')";
40+
private final String sqlGetItemTables = "SELECT hypertable_name as table_name FROM timescaledb_information.hypertables WHERE hypertable_name != '\"#itemsManageTable#\"'";
3841

3942
@Override
4043
public Properties getConnectionProperties() {
@@ -46,6 +49,10 @@ public Properties getConnectionProperties() {
4649
return properties;
4750
}
4851

52+
/*************
53+
* ITEM DAOs *
54+
*************/
55+
4956
@Override
5057
public void doCreateItemTable(ItemVO vo) throws JdbcSQLException {
5158
super.doCreateItemTable(vo);
@@ -58,4 +65,16 @@ public void doCreateItemTable(ItemVO vo) throws JdbcSQLException {
5865
throw new JdbcSQLException(e);
5966
}
6067
}
68+
69+
@Override
70+
public List<ItemsVO> doGetItemTables(ItemsVO vo) throws JdbcSQLException {
71+
String sql = StringUtilsExt.replaceArrayMerge(sqlGetItemTables, new String[] { "#itemsManageTable#" },
72+
new String[] { vo.getItemsManageTable() });
73+
this.logger.debug("JDBC::doGetItemTables sql={}", sql);
74+
try {
75+
return Yank.queryBeanList(sql, ItemsVO.class, null);
76+
} catch (YankSQLException e) {
77+
throw new JdbcSQLException(e);
78+
}
79+
}
6180
}

0 commit comments

Comments
 (0)
Please sign in to comment.