Skip to content

Commit b37d21b

Browse files
committed
feat: enhance DBeaver support for GaussDB catalogs
- Updated clone-build-deps.sh to include a new patch script for GaussDB database catalog support. - Added patch-dbeaver-gaussdb-catalogs.sh to modify GenericDataSource.java for listing all databases in GaussDB using pg_database.
1 parent c7161eb commit b37d21b

2 files changed

Lines changed: 114 additions & 1 deletion

File tree

deploy/scripts/clone-build-deps.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ echo "DBeaver branch: $DBEAVER_BRANCH"
2222

2323
chmod a+x $SCRIPT_DIR/*sh
2424

25-
# 对 dbeaver 打达梦、GaussDB 驱动补丁
25+
# 对 dbeaver 打达梦、GaussDB 驱动补丁及 GaussDB 数据库列表补丁
2626
"$SCRIPT_DIR/patch-dbeaver-dameng.sh" "$(pwd)/dbeaver"
2727
"$SCRIPT_DIR/patch-dbeaver-gaussdb.sh" "$(pwd)/dbeaver"
28+
"$SCRIPT_DIR/patch-dbeaver-gaussdb-catalogs.sh" "$(pwd)/dbeaver"
2829

2930
echo "Clone and patch done. You can run build from cloudbeaver/deploy (e.g. ./build-backend.sh)."
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/bin/bash
2+
# 让 Generic 驱动下使用 PostgreSQL JDBC 的数据源(如 GaussDB)通过 pg_database 列出所有数据库,
3+
# 而不是仅显示当前连接的数据库。
4+
# 用法: 传入 dbeaver 根目录
5+
set -e
6+
7+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8+
if [ -n "$1" ]; then
9+
DBEAVER_ROOT="$1"
10+
else
11+
DBEAVER_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)/../dbeaver"
12+
fi
13+
14+
JAVA_FILE="${DBEAVER_ROOT}/plugins/org.jkiss.dbeaver.ext.generic/src/org/jkiss/dbeaver/ext/generic/model/GenericDataSource.java"
15+
if [ ! -f "$JAVA_FILE" ]; then
16+
echo "GenericDataSource.java not found: $JAVA_FILE"
17+
echo "Usage: $0 [dbeaver_root]"
18+
exit 1
19+
fi
20+
21+
if grep -q 'isPostgreSQLCompatible' "$JAVA_FILE"; then
22+
echo "GenericDataSource already patched for PostgreSQL/GaussDB catalogs, skip."
23+
exit 0
24+
fi
25+
26+
python3 - "$JAVA_FILE" << 'PY'
27+
import sys
28+
path = sys.argv[1]
29+
with open(path, "r", encoding="utf-8", errors="replace") as f:
30+
content = f.read()
31+
32+
# 在 getCatalogsNames 方法开头、 "final List<String> catalogNames = new ArrayList<>();" 之后
33+
# 插入 isPostgreSQLCompatible 方法和 PostgreSQL 分支;并把原 try 保留为 else 分支
34+
old_sig = """ public List<String> getCatalogsNames(
35+
@NotNull DBRProgressMonitor monitor,
36+
@NotNull JDBCDatabaseMetaData metaData,
37+
GenericMetaObject catalogObject,
38+
@Nullable DBSObjectFilter catalogFilters
39+
) throws DBException {
40+
final List<String> catalogNames = new ArrayList<>();
41+
try {
42+
try (JDBCResultSet dbResult = metaData.getCatalogs()) {"""
43+
44+
new_block = """ /**
45+
* True if this connection uses PostgreSQL JDBC (e.g. PostgreSQL, GaussDB, openGauss).
46+
* Such drivers report only the current database from getCatalogs(); we use pg_database to list all.
47+
*/
48+
private boolean isPostgreSQLCompatible() {
49+
String driverClass = getContainer().getDriver().getDriverClassName();
50+
if (driverClass != null && driverClass.contains("postgresql")) {
51+
return true;
52+
}
53+
String url = getContainer().getConnectionConfiguration().getUrl();
54+
return url != null && url.startsWith("jdbc:postgresql:");
55+
}
56+
57+
public List<String> getCatalogsNames(
58+
@NotNull DBRProgressMonitor monitor,
59+
@NotNull JDBCDatabaseMetaData metaData,
60+
GenericMetaObject catalogObject,
61+
@Nullable DBSObjectFilter catalogFilters
62+
) throws DBException {
63+
final List<String> catalogNames = new ArrayList<>();
64+
// PostgreSQL JDBC getCatalogs() returns only the current database; use pg_database for full list
65+
if (isPostgreSQLCompatible()) {
66+
String pgDatabaseSql = "SELECT datname FROM pg_catalog.pg_database WHERE NOT datistemplate AND datallowconn ORDER BY datname";
67+
try {
68+
try (JDBCSession session = DBUtils.openMetaSession(monitor, this, "Read database list")) {
69+
try (JDBCStatement stmt = session.createStatement()) {
70+
try (JDBCResultSet rs = stmt.executeQuery(pgDatabaseSql)) {
71+
while (rs.next()) {
72+
String name = JDBCUtils.safeGetStringTrimmed(rs, 1);
73+
if (CommonUtils.isNotEmpty(name)) {
74+
if (catalogFilters == null || catalogFilters.matches(name)) {
75+
catalogNames.add(name);
76+
monitor.subTask("Extract catalogs - " + name);
77+
} else {
78+
catalogsFiltered = true;
79+
}
80+
if (monitor.isCanceled()) {
81+
break;
82+
}
83+
}
84+
}
85+
}
86+
}
87+
}
88+
if (catalogNames.size() == 1 && omitSingleCatalog) {
89+
catalogNames.clear();
90+
}
91+
return catalogNames;
92+
} catch (SQLException e) {
93+
if (metaModel.isCatalogsOptional()) {
94+
log.warn("Can't read database list from pg_database", e);
95+
return catalogNames;
96+
}
97+
throw new DBException("Error reading database list", e);
98+
}
99+
}
100+
try {
101+
try (JDBCResultSet dbResult = metaData.getCatalogs()) {"""
102+
103+
if old_sig not in content:
104+
sys.exit("Could not find getCatalogsNames insertion point in GenericDataSource.java")
105+
content = content.replace(old_sig, new_block, 1)
106+
107+
with open(path, "w", encoding="utf-8") as f:
108+
f.write(content)
109+
print("Patched GenericDataSource.java: PostgreSQL/GaussDB full database list via pg_database.")
110+
PY
111+
112+
echo "Done."

0 commit comments

Comments
 (0)