diff --git a/.gitignore b/.gitignore index d3f413121b8..ea3790b7f83 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,7 @@ workspace-dev-ce/ deploy/cloudbeaver server/**/target apps/**/target -osgi-cache/ \ No newline at end of file +osgi-cache/ + +web +.idea diff --git a/deploy/scripts/clone-build-deps.sh b/deploy/scripts/clone-build-deps.sh index a694c595596..04e402f8f5d 100755 --- a/deploy/scripts/clone-build-deps.sh +++ b/deploy/scripts/clone-build-deps.sh @@ -20,7 +20,11 @@ echo "DBeaver branch: $DBEAVER_BRANCH" [ ! -d dbeaver-common ] && git clone --depth 1 -b "$DBEAVER_BRANCH" https://github.com/dbeaver/dbeaver-common.git [ ! -d dbeaver-jdbc-libsql ] && git clone --depth 1 -b "$DBEAVER_BRANCH" https://github.com/dbeaver/dbeaver-jdbc-libsql.git -# 对 dbeaver 打达梦驱动补丁 +chmod a+x $SCRIPT_DIR/*sh + +# 对 dbeaver 打达梦、GaussDB 驱动补丁及 GaussDB 数据库列表补丁 "$SCRIPT_DIR/patch-dbeaver-dameng.sh" "$(pwd)/dbeaver" +"$SCRIPT_DIR/patch-dbeaver-gaussdb.sh" "$(pwd)/dbeaver" +"$SCRIPT_DIR/patch-dbeaver-gaussdb-catalogs.sh" "$(pwd)/dbeaver" echo "Clone and patch done. You can run build from cloudbeaver/deploy (e.g. ./build-backend.sh)." diff --git a/deploy/scripts/launch-product.sh b/deploy/scripts/launch-product.sh old mode 100644 new mode 100755 diff --git a/deploy/scripts/patch-dbeaver-gaussdb-catalogs.sh b/deploy/scripts/patch-dbeaver-gaussdb-catalogs.sh new file mode 100755 index 00000000000..6fbea557c34 --- /dev/null +++ b/deploy/scripts/patch-dbeaver-gaussdb-catalogs.sh @@ -0,0 +1,112 @@ +#!/bin/bash +# 让 Generic 驱动下使用 PostgreSQL JDBC 的数据源(如 GaussDB)通过 pg_database 列出所有数据库, +# 而不是仅显示当前连接的数据库。 +# 用法: 传入 dbeaver 根目录 +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [ -n "$1" ]; then + DBEAVER_ROOT="$1" +else + DBEAVER_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)/../dbeaver" +fi + +JAVA_FILE="${DBEAVER_ROOT}/plugins/org.jkiss.dbeaver.ext.generic/src/org/jkiss/dbeaver/ext/generic/model/GenericDataSource.java" +if [ ! -f "$JAVA_FILE" ]; then + echo "GenericDataSource.java not found: $JAVA_FILE" + echo "Usage: $0 [dbeaver_root]" + exit 1 +fi + +if grep -q 'isPostgreSQLCompatible' "$JAVA_FILE"; then + echo "GenericDataSource already patched for PostgreSQL/GaussDB catalogs, skip." + exit 0 +fi + +python3 - "$JAVA_FILE" << 'PY' +import sys +path = sys.argv[1] +with open(path, "r", encoding="utf-8", errors="replace") as f: + content = f.read() + +# 在 getCatalogsNames 方法开头、 "final List catalogNames = new ArrayList<>();" 之后 +# 插入 isPostgreSQLCompatible 方法和 PostgreSQL 分支;并把原 try 保留为 else 分支 +old_sig = """ public List getCatalogsNames( + @NotNull DBRProgressMonitor monitor, + @NotNull JDBCDatabaseMetaData metaData, + GenericMetaObject catalogObject, + @Nullable DBSObjectFilter catalogFilters + ) throws DBException { + final List catalogNames = new ArrayList<>(); + try { + try (JDBCResultSet dbResult = metaData.getCatalogs()) {""" + +new_block = """ /** + * True if this connection uses PostgreSQL JDBC (e.g. PostgreSQL, GaussDB, openGauss). + * Such drivers report only the current database from getCatalogs(); we use pg_database to list all. + */ + private boolean isPostgreSQLCompatible() { + String driverClass = getContainer().getDriver().getDriverClassName(); + if (driverClass != null && driverClass.contains("postgresql")) { + return true; + } + String url = getContainer().getConnectionConfiguration().getUrl(); + return url != null && url.startsWith("jdbc:postgresql:"); + } + + public List getCatalogsNames( + @NotNull DBRProgressMonitor monitor, + @NotNull JDBCDatabaseMetaData metaData, + GenericMetaObject catalogObject, + @Nullable DBSObjectFilter catalogFilters + ) throws DBException { + final List catalogNames = new ArrayList<>(); + // PostgreSQL JDBC getCatalogs() returns only the current database; use pg_database for full list + if (isPostgreSQLCompatible()) { + String pgDatabaseSql = "SELECT datname FROM pg_catalog.pg_database WHERE NOT datistemplate AND datallowconn ORDER BY datname"; + try { + try (JDBCSession session = DBUtils.openMetaSession(monitor, this, "Read database list")) { + try (JDBCStatement stmt = session.createStatement()) { + try (JDBCResultSet rs = stmt.executeQuery(pgDatabaseSql)) { + while (rs.next()) { + String name = JDBCUtils.safeGetStringTrimmed(rs, 1); + if (CommonUtils.isNotEmpty(name)) { + if (catalogFilters == null || catalogFilters.matches(name)) { + catalogNames.add(name); + monitor.subTask("Extract catalogs - " + name); + } else { + catalogsFiltered = true; + } + if (monitor.isCanceled()) { + break; + } + } + } + } + } + } + if (catalogNames.size() == 1 && omitSingleCatalog) { + catalogNames.clear(); + } + return catalogNames; + } catch (SQLException e) { + if (metaModel.isCatalogsOptional()) { + log.warn("Can't read database list from pg_database", e); + return catalogNames; + } + throw new DBException("Error reading database list", e); + } + } + try { + try (JDBCResultSet dbResult = metaData.getCatalogs()) {""" + +if old_sig not in content: + sys.exit("Could not find getCatalogsNames insertion point in GenericDataSource.java") +content = content.replace(old_sig, new_block, 1) + +with open(path, "w", encoding="utf-8") as f: + f.write(content) +print("Patched GenericDataSource.java: PostgreSQL/GaussDB full database list via pg_database.") +PY + +echo "Done." \ No newline at end of file diff --git a/deploy/scripts/patch-dbeaver-gaussdb.sh b/deploy/scripts/patch-dbeaver-gaussdb.sh new file mode 100755 index 00000000000..79f9375bda3 --- /dev/null +++ b/deploy/scripts/patch-dbeaver-gaussdb.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# 在 DBeaver generic 插件中插入 GaussDB/openGauss ( gaussdb_jdbc ) 驱动定义 +# 用法: 传入 dbeaver 根目录,或从 cloudbeaver 仓库根目录的上一级执行 +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [ -n "$1" ]; then + DBEAVER_ROOT="$1" +else + DBEAVER_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)/../dbeaver" +fi + +PLUGIN_XML="${DBEAVER_ROOT}/plugins/org.jkiss.dbeaver.ext.generic/plugin.xml" +if [ ! -f "$PLUGIN_XML" ]; then + echo "DBeaver plugin.xml not found: $PLUGIN_XML" + echo "Usage: $0 [dbeaver_root]" + exit 1 +fi + +if grep -q 'id="gaussdb_jdbc"' "$PLUGIN_XML"; then + echo "GaussDB driver already present in DBeaver plugin.xml, skip patch." + exit 0 +fi + +python3 - "$PLUGIN_XML" << 'PY' +import sys +path = sys.argv[1] +marker = "" +driver_block = ''' + + + + ''' + +with open(path, "r", encoding="utf-8", errors="replace") as f: + content = f.read() +if marker not in content: + sys.exit("Marker not found in plugin.xml") +new_content = content.replace(marker, driver_block, 1) +with open(path, "w", encoding="utf-8") as f: + f.write(new_content) +print("Patched DBeaver plugin.xml: added gaussdb_jdbc driver.") +PY + +echo "Done." diff --git a/server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml b/server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml index 1e50351223c..2fe272b9da1 100644 --- a/server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml +++ b/server/bundles/io.cloudbeaver.resources.drivers.base/plugin.xml @@ -22,6 +22,7 @@ + @@ -46,6 +47,7 @@ + @@ -71,6 +73,7 @@ + diff --git a/server/drivers/gaussdb/lib/gsjdbc4-1.1.jar b/server/drivers/gaussdb/lib/gsjdbc4-1.1.jar new file mode 100644 index 00000000000..a7f518b202d Binary files /dev/null and b/server/drivers/gaussdb/lib/gsjdbc4-1.1.jar differ diff --git a/server/drivers/gaussdb/pom.xml b/server/drivers/gaussdb/pom.xml new file mode 100644 index 00000000000..5a45eb42ebb --- /dev/null +++ b/server/drivers/gaussdb/pom.xml @@ -0,0 +1,49 @@ + + 4.0.0 + drivers.gaussdb + 1.0.0 + + io.cloudbeaver + drivers + 1.0.0 + ../ + + + + gaussdb + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.6 + + + copy-gaussdb-jar + validate + + ../../../deploy/drivers/gaussdb + true + + + lib + + *.jar + + + + + + copy-resources + + + + + + + + diff --git a/server/drivers/pom.xml b/server/drivers/pom.xml index 5371447bf65..f3d9a9b9517 100644 --- a/server/drivers/pom.xml +++ b/server/drivers/pom.xml @@ -22,6 +22,7 @@ db2 db2-jt400 duckdb + gaussdb h2 h2_v2 hive2