From 0e4db710856fc8da452f22a4b40d352954538a2a Mon Sep 17 00:00:00 2001 From: linxiaotao Date: Tue, 27 Jan 2026 09:24:35 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=92=8C=E8=A1=A5?= =?UTF-8?q?=E5=85=85=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=9E=84=E5=BB=BA=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ci/RPM_BUILD_FLOW.md | 80 ++++++++++++++++++++++++++++++++------- ci/docker/IMAGE_CONFIG.md | 47 +++++++++++++++++++++++ 2 files changed, 113 insertions(+), 14 deletions(-) create mode 100644 ci/docker/IMAGE_CONFIG.md diff --git a/ci/RPM_BUILD_FLOW.md b/ci/RPM_BUILD_FLOW.md index 5a2b10189c..a45354927e 100644 --- a/ci/RPM_BUILD_FLOW.md +++ b/ci/RPM_BUILD_FLOW.md @@ -14,7 +14,7 @@ | **4. Frontend** | 前端编译 | `./ci/docker/manage_container.sh exec "./ci/script/build_frontend.sh"` | 默认 | Container | 编译前端代码 | | **5. Backend** | 后端编译 | `./ci/docker/manage_container.sh exec "./ci/script/build_backend.sh"` | 默认 | Container | 编译后端代码 | | **6. Package** | RPM 打包 | `./ci/docker/manage_container.sh exec "./ci/script/build_rpm_pkg.sh"` | 默认 | Container | 打包 RPM 文件 | -| **7. Cleanup** | 销毁容器 | `./ci/docker/manage_container.sh stop` | **Always / Any** | Host | 清理容器资源 | +| **7. Cleanup** | 销毁容器 | `./ci/docker/manage_container.sh stop` | **Always** | Host | 无论成功或失败都执行,清理容器资源 | --- @@ -25,15 +25,15 @@ | 层次 | 职责 | 环境说明 | | :--- | :--- | :--- | | **Host (GoCD Agent)** | 源码同步、生命周期管理 | 无 `sudo` 权限,仅需安装 `docker` | -| **Container (Build Image)** | 编译前端、编译后端、RPM 打包 | 预装 JDK8, Maven (Aliyun), Node18, pnpm10 | +| **Container (Build Image)** | 编译前端、编译后端、RPM 打包 | 预装 JDK8, Maven 3.6.3 (仓库使用 Aliyun 镜像), Node18, pnpm10 | ### 路径映射定义 | 定义项 | Host 路径 (GoCD Agent) | Container 路径 | 说明 | | :--- | :--- | :--- | :--- | | **工作目录** | `/var/lib/go-agent/pipelines/odc/` | `/root/odc` | 流水线根目录 | -| **代码目录** | `source_code/` | `/root/odc/source_code` | 挂载项目源码 | -| **最终产物** | `source_code/*.rpm` | `/root/odc/source_code/*.rpm` | 构建完成的 RPM 包 | +| **代码目录** | 项目根目录(如 `$PROJECT_ROOT`) | `/root/odc/source_code` | 整个项目根目录挂载到容器内 | +| **最终产物** | `*.rpm` | `/root/odc/source_code/*.rpm` | 构建完成的 RPM 包(位于项目根目录) | --- @@ -76,7 +76,7 @@ flowchart TD | :--- | :--- | :--- | | **基础镜像** | Ubuntu 22.04 | 更好的兼容性与国内源支持 | | **Java 环境** | OpenJDK 8 | 后端编译必需 | -| **Maven 环境** | Maven 3.6.3 | **配置 Aliyun 镜像源加速** | +| **Maven 环境** | Maven 3.6.3 | **从华为云镜像下载,Maven 仓库配置 Aliyun 镜像源加速** | | **Node.js 环境** | Node.js 18.20.0 | 满足 pnpm 10 运行要求 | | **前端工具** | pnpm 10.28.1 | **配置 npmmirror 镜像源加速** | | **系统工具** | `rpm`, `file`, `git`, `xz-utils` | 打包及工具链 | @@ -98,6 +98,24 @@ docker push reg.actiontech.com/actiontech-dev/odc/build-env:1.0 > 1. 上述镜像是流水线的默认配置。 > 2. 若需在 GoCD 中临时切换镜像,请设置环境变量 `ODC_BUILD_IMAGE`。 > 3. 若只需修改部分参数,可单独设置 `ODC_REGISTRY` 或 `ODC_TAG`。 + +### 3.2 容器启动时的环境变量传递 + +容器启动时(`manage_container.sh start`),会自动将以下环境变量传递到容器内: + +- **必需变量**: + - `IS_IN_CONTAINER=1`:标识运行在容器内 + - `SYNC_SUBMODULE=1`:启用子模块同步 + - `BUILD_FRONTEND=1`:启用前端构建 + +- **可配置变量**(从 Host 环境继承,未设置时使用默认值): + - `RPM_RELEASE`:默认当前日期 `$(date +%Y%m%d)` + - `ODC_UI_BRANCH`:默认 `dev-4.3.4-v2`(容器启动时的后备值) + - `ODC_SERVER_BRANCH`:默认 `test/build_rpm`(容器启动时的后备值) + - `ODC_UI_URL`、`ODC_BUILD_RESOURCE_URL`、`ODC_BUILD_IMAGE` + +> **重要**:容器启动时使用的默认值与 `env_init.sh` 中的标准默认值可能不同。建议在 GoCD 中显式设置这些环境变量,或在步骤 1(Switch Branches)中通过 `env_init.sh` 统一初始化。 + --- ## 4. 关键脚本说明 @@ -105,11 +123,19 @@ docker push reg.actiontech.com/actiontech-dev/odc/build-env:1.0 ### 4.1 分支切换 (`ci/script/switch_branches.sh`) 在主机上执行,负责: - **环境变量输出**: 初始化环境变量默认值并打印关键环境变量 -- **后端分支切换**: 切换到 `ODC_SERVER_BRANCH` 指定的分支(默认 `test/build_rpm`) -- **前端分支切换**: 通过子模块同步切换到 `ODC_UI_BRANCH` 指定的分支(默认 `dev-4.3.4-v2`) +- **后端分支切换**: 切换到 `ODC_SERVER_BRANCH` 指定的分支(默认 `dev/4.3.4`,由 `env_init.sh` 设置) +- **前端分支切换**: 通过子模块同步切换到 `ODC_UI_BRANCH` 指定的分支(默认 `dev-4.3.4`,由 `env_init.sh` 设置) + +> **注意**:如果未设置环境变量,`switch_branches.sh` 和 `manage_container.sh` 中会使用后备默认值(`test/build_rpm` 和 `dev-4.3.4-v2`),但 `env_init.sh` 中的标准默认值是 `dev/4.3.4` 和 `dev-4.3.4`。建议在 GoCD 中显式设置这些环境变量以避免混淆。 ### 4.2 生命周期管理 (`ci/docker/manage_container.sh`) -- **start**: 自动拉取远程镜像,启动常驻容器,并初始化 Git `safe.directory` 权限。 +- **start**: 自动拉取远程镜像,启动常驻容器,并初始化 Git `safe.directory` 权限。启动时会传递以下环境变量到容器: + - `IS_IN_CONTAINER=1` + - `RPM_RELEASE`(默认当前日期) + - `ODC_UI_BRANCH`(默认 `dev-4.3.4-v2`) + - `ODC_SERVER_BRANCH`(默认 `test/build_rpm`) + - `ODC_UI_URL`、`ODC_BUILD_RESOURCE_URL`、`ODC_BUILD_IMAGE` + - `SYNC_SUBMODULE=1`、`BUILD_FRONTEND=1` - **exec**: 在运行中的容器内执行指定命令,并实时流式输出日志。 - **stop**: 停止并销毁容器,确保 Agent 环境整洁。 @@ -119,7 +145,22 @@ docker push reg.actiontech.com/actiontech-dev/odc/build-env:1.0 - **环境变量打印**: 以表格形式打印所有关键环境变量 - **系统环境检查**: 检查 OS、系统工具、Java、Maven、Node 等依赖 -### 4.4 本地一键构建 (`ci/docker/run_build.sh`) +### 4.4 前端构建 (`ci/script/build_frontend.sh`) +在容器内执行,负责: +- **前端编译**: 使用 pnpm 编译前端代码,生成前端构建产物 + +### 4.5 后端构建 (`ci/script/build_backend.sh`) +在容器内执行,包含以下步骤: +- **安装本地依赖**: 安装项目所需的本地库依赖 +- **准备 Obclient 驱动**: 从 `build-resource` 子模块复制 `obclient.tar.gz` 到 `import/` 目录(支持 x86_64 和 aarch64 架构) +- **编译后端 JAR**: 使用 Maven 编译后端核心 JAR 文件(支持通过 `BUILD_PROFILE` 指定 Maven Profile) + +### 4.6 RPM 打包 (`ci/script/build_rpm_pkg.sh`) +在容器内执行,包含以下步骤: +- **构建 RPM 包**: 使用 Maven 和 RPM 工具构建 RPM 安装包 +- **整理构建产物**: 组织并整理构建生成的 RPM 文件 + +### 4.7 本地一键构建 (`ci/docker/run_build.sh`) 封装了从 Host 端分支切换到容器内全流程构建的逻辑,用于本地开发环境快速验证。 --- @@ -128,8 +169,19 @@ docker push reg.actiontech.com/actiontech-dev/odc/build-env:1.0 | 变量名 | 默认值 | 用途说明 | | :--- | :--- | :--- | -| `RPM_RELEASE` | 当前日期 | RPM 包的 Release 号 | -| `BUILD_PROFILE` | - | Maven Profile (如 `oss`) | -| `FETCH_FROM_OSS` | `0` | 是否从 OSS 获取 `obclient.tar.gz` | -| `IS_IN_CONTAINER` | `1` | 标识当前运行在容器内 | -| `CI` | `true` | 开启工具链的非交互模式 | +| `RPM_RELEASE` | 当前日期 (YYYYMMDD) | RPM 包的 Release 号 | +| `ODC_SERVER_BRANCH` | `dev/4.3.4` | 后端代码分支(`env_init.sh` 中的标准默认值) | +| `ODC_UI_BRANCH` | `dev-4.3.4` | 前端代码分支(`env_init.sh` 中的标准默认值) | +| `ODC_UI_URL` | `https://github.com/actiontech/odc-client.git` | 前端子模块的 Git 仓库地址 | +| `ODC_BUILD_RESOURCE_URL` | `https://github.com/winfredLIN/odc-build-resource.git` | build-resource 子模块的 Git 仓库地址 | +| `ODC_BUILD_IMAGE` | `reg.actiontech.com/actiontech-dev/odc/build-env:1.0` | 构建容器镜像名称 | +| `ODC_REGISTRY` | `reg.actiontech.com` | Docker 镜像仓库地址(用于构建 `ODC_BUILD_IMAGE`) | +| `ODC_REPOSITORY` | `actiontech-dev/odc/build-env` | Docker 镜像仓库路径(用于构建 `ODC_BUILD_IMAGE`) | +| `ODC_TAG` | `1.0` | Docker 镜像标签(用于构建 `ODC_BUILD_IMAGE`) | +| `SYNC_SUBMODULE` | `1` | 是否同步子模块(1=是,0=否) | +| `BUILD_FRONTEND` | `1` | 是否构建前端(1=是,0=否) | +| `BUILD_PROFILE` | 无(可选) | Maven Profile,如 `oss`。不设置则不使用 Profile | +| `FETCH_FROM_OSS` | `0` | 是否从 OSS 获取 `obclient.tar.gz`(当前未实现,功能预留) | +| `IS_IN_CONTAINER` | `1` | 标识当前运行在容器内(由容器启动脚本自动设置) | +| `CI` | `true` | 开启工具链的非交互模式(在 Dockerfile 中设置) | +| `GO_PIPELINE_NAME` | 无 | GoCD 流水线名称(用于生成容器名称,默认容器名为 `odc-builder`) | diff --git a/ci/docker/IMAGE_CONFIG.md b/ci/docker/IMAGE_CONFIG.md new file mode 100644 index 0000000000..4a8a8e9aa6 --- /dev/null +++ b/ci/docker/IMAGE_CONFIG.md @@ -0,0 +1,47 @@ +# ODC 构建镜像配置说明 + +本文档说明构建镜像中的配置与构建依赖的对应关系。 + +## 镜像信息 + +- **镜像名称**: `reg.actiontech.com/actiontech-dev/odc/build-env:1.0` +- **基础镜像**: Ubuntu 22.04 +- **用途**: ODC RPM 包构建流水线 + +## 构建依赖配置对照表 + +| 构建依赖 | 镜像配置 | 版本 | 用途说明 | +| :--- | :--- | :--- | :--- | +| **Java 环境** | `openjdk-8-jdk` (apt 安装) | OpenJDK 8 | 后端代码编译 | +| **Maven** | 从华为云镜像下载安装 | 3.6.3 | Java 项目构建工具 | +| **Maven 仓库** | 配置阿里云镜像源 (`/root/.m2/settings.xml`) | - | 加速 Maven 依赖下载 | +| **Node.js** | 从清华镜像下载安装 | 18.20.0 | 前端构建运行时 | +| **pnpm** | 通过 npm 全局安装 | 10.28.1 | 前端包管理工具 | +| **pnpm 仓库** | 配置 npmmirror 镜像源 | - | 加速前端依赖下载 | +| **RPM 工具** | `rpm` (apt 安装) | - | RPM 包构建 | +| **Git** | `git` (apt 安装) | - | 代码版本管理 | +| **系统工具** | `file`, `curl`, `zip`, `unzip`, `make`, `gcc`, `g++`, `xz-utils`, `ca-certificates` | - | 构建过程所需的基础工具 | + +## 环境变量配置 + +| 环境变量 | 值 | 说明 | +| :--- | :--- | :--- | +| `JAVA_HOME` | `/usr/lib/jvm/java-8-openjdk-amd64` | Java 安装路径 | +| `MAVEN_HOME` | `/usr/local/maven` | Maven 安装路径 | +| `NODE_VERSION` | `18.20.0` | Node.js 版本 | +| `PATH` | `$MAVEN_HOME/bin:$PATH` | 包含 Maven 可执行文件路径 | +| `CI` | `true` | 启用非交互模式 | + +## 镜像源配置 + +| 工具 | 镜像源 | 说明 | +| :--- | :--- | :--- | +| **Ubuntu APT** | `mirrors.aliyun.com` | 系统包管理器镜像源 | +| **Maven 仓库** | `https://maven.aliyun.com/repository/public` | Maven 依赖下载镜像源 | +| **Node.js** | `mirrors.tuna.tsinghua.edu.cn` | Node.js 二进制下载镜像源 | +| **npm/pnpm** | `https://registry.npmmirror.com` | npm 包注册表镜像源 | + +## 工作目录 + +- **工作目录**: `/root/odc` +- **默认命令**: `/bin/bash` From 68892c70f2d8b866f6a0f088121ac6e6d116d31f Mon Sep 17 00:00:00 2001 From: linxiaotao Date: Tue, 27 Jan 2026 10:28:39 +0000 Subject: [PATCH 2/4] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=95=B0=E6=8D=AE=E5=BA=93=E6=8F=92=E4=BB=B6=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E5=81=9A=E7=9A=84=E4=BA=8B=E6=83=85=E7=9A=84=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/add_a_new_plugin_how_to.md | 175 ++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 docs/add_a_new_plugin_how_to.md diff --git a/docs/add_a_new_plugin_how_to.md b/docs/add_a_new_plugin_how_to.md new file mode 100644 index 0000000000..6539f90ea1 --- /dev/null +++ b/docs/add_a_new_plugin_how_to.md @@ -0,0 +1,175 @@ +# 如何新增一个数据库插件 (以 SQLServer 为例) + +本文档旨在指导开发者如何在 ODC 中新增一个数据库插件,并以 SQLServer 的实现作为参考。 + +## 1. 架构概述 + +ODC 的数据库适配遵循“逻辑下沉、接口隔离”原则,主要分为以下几个层次: + +- **`libs/db-browser` (基础适配层)**:提供数据库方言的原子操作,如元数据查询(Schema)、SQL 生成(Editor)、SQL 模板(Template)等。 +- **`server/plugins` (插件扩展层)**:基于 PF4J 机制,将 `db-browser` 的能力封装为 ODC Server 可用的扩展点(Extension Point)。 +- **`server/odc-core` (核心逻辑层)**:处理 SQL 拆分(SqlSplitter)等跨模块的基础能力。 + +--- + +## 2. 基础适配层:`libs/db-browser` + +在该层中,我们需要实现 SQLServer 的方言适配逻辑。 + +### 2.1 目录结构与文件说明 + +```text +libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/ +├── schema/sqlserver/ +│ ├── SqlServerSchemaAccessor.java +│ └── SqlServerSchemaUtil.java +├── editor/sqlserver/ +│ ├── SqlServerColumnEditor.java +│ ├── SqlServerConstraintEditor.java +│ ├── SqlServerIndexEditor.java +│ ├── SqlServerMViewEditor.java +│ ├── SqlServerObjectOperator.java +│ ├── SqlServerPartitionEditor.java +│ ├── SqlServerSequenceEditor.java +│ ├── SqlServerSynonymEditor.java +│ ├── SqlServerTableEditor.java +│ ├── SqlServerTriggerEditor.java +│ └── SqlServerViewEditor.java +├── template/sqlserver/ +│ ├── SqlServerFunctionTemplate.java +│ ├── SqlServerProcedureTemplate.java +│ ├── SqlServerTriggerTemplate.java +│ └── SqlServerViewTemplate.java +└── util/ + ├── SqlServerSqlBuilder.java + └── StringUtils.java (工具类增强) +``` + +| 文件名 | 作用说明 | +| :--- | :--- | +| `SqlServerSchemaAccessor.java` | 实现 `DBSchemaAccessor` 接口,通过系统视图查询表、列、索引、约束等元数据。 | +| `SqlServerSchemaUtil.java` | 封装 SQLServer 特有的元数据处理工具方法。 | +| `SqlServerTableEditor.java` | 实现 `DBTableEditor`,负责生成表的 `CREATE`, `ALTER`, `DROP`, `RENAME` 等 DDL。 | +| `SqlServerColumnEditor.java` | 负责生成列相关的 DDL 语句。 | +| `SqlServerIndexEditor.java` | 负责生成索引相关的 DDL 语句。 | +| `SqlServerConstraintEditor.java` | 负责生成约束(主键、外键、唯一键、Check)相关的 DDL 语句。 | +| `SqlServerObjectOperator.java` | 实现 `DBObjectOperator`,执行通用的数据库对象操作(如删除、统计等)。 | +| `SqlServerFunctionTemplate.java` | 提供新建函数时的初始 SQL 模板。 | +| `SqlServerSqlBuilder.java` | 继承 `SqlBuilder`,处理 SQLServer 特有的标识符引用(`[]`)和值转义。 | +| `StringUtils.java` | 增加 `quoteSqlServerIdentifier` 和 `quoteSqlServerValue` 等工具方法。 | + +### 2.2 核心逻辑实现 + +- **元数据访问**: SQLServer 支持 `database.schema` 结构。为了兼容 ODC 的单层 Schema 模型,我们将 `database.schema` 组合作为一个统一的 `schemaName` 返回。 +- **SQL 生成**: 使用 `SqlServerSqlBuilder` 确保生成的 SQL 符合 SQLServer 语法规范。 + +--- + +## 3. 业务扩展层:`server/plugins` + +该层负责将 `db-browser` 的能力注册到 ODC 插件系统中。 + +### 3.1 连接插件 (Connect Plugin) + +**目录结构**: `server/plugins/connect-plugin-sqlserver/src/main/java/com/oceanbase/odc/plugin/connect/sqlserver/` + +| 文件名 | 作用说明 | +| :--- | :--- | +| `SqlServerConnectionPlugin.java` | 插件入口类,定义插件 ID 和扩展点。 | +| `SqlServerConnectionExtension.java` | 实现 `ConnectionExtensionPoint`,处理驱动加载、连接测试。 | +| `SqlServerJdbcUrlParser.java` | 实现 `JdbcUrlParser`,解析 SQLServer JDBC URL 属性。 | +| `SqlServerSessionExtension.java` | 实现 `SessionExtensionPoint`,处理会话初始化、Schema 切换(`USE`)、获取连接 ID(`@@SPID`)。 | +| `SqlServerInformationExtension.java` | 提供数据库版本、特性支持等信息。 | +| `SqlServerDiagnoseExtensionPoint.java` | 实现 SQL 诊断、执行计划获取等功能。 | + +### 3.2 Schema 插件 (Schema Plugin) + +**目录结构**: `server/plugins/schema-plugin-sqlserver/src/main/java/com/oceanbase/odc/plugin/schema/sqlserver/` + +| 文件名 | 作用说明 | +| :--- | :--- | +| `SqlServerSchemaPlugin.java` | 实现 `BaseSchemaPlugin`,注册 SQLServer 的 Schema 访问能力。 | +| `SqlServerTableExtension.java` | 将 `db-browser` 的 `SqlServerSchemaAccessor` 桥接到 ODC 的表管理接口。 | +| `SqlServerDatabaseExtension.java` | 处理数据库/Schema 列表的获取。 | +| `SqlServerViewExtension.java` | 处理视图元数据的获取。 | +| `SqlServerFunctionExtension.java` | 处理函数元数据的获取。 | + +--- + +## 4. 核心逻辑增强:`server/odc-core` + +### 4.1 SQL 拆分器 (SqlSplitter) + +**路径**: `server/odc-core/src/main/java/com/oceanbase/odc/core/sql/split/SqlServerSqlSplitter.java` + +| 文件名 | 作用说明 | +| :--- | :--- | +| `SqlServerSqlSplitter.java` | 实现 SQLServer 脚本拆分逻辑,支持 `GO` 分隔符,识别 `BEGIN...END` 块以避免错误切分。 | + +--- + +## 5. 全局集成与注册 + +除了实现插件本身的逻辑外,还需要在 ODC 核心模块中进行注册,使系统能够识别并调用新插件。 + +### 5.1 `libs/db-browser` 工厂注册 + +| 工厂类 | 注册操作 | +| :--- | :--- | +| `AbstractDBBrowserFactory.java` | 在 `create()` 方法的 switch 中增加 `SQL_SERVER` 分支,并添加 `buildForSqlServer()` 抽象方法。 | +| `DBSchemaAccessorFactory.java` | 实现 `buildForSqlServer()`,返回 `SqlServerSchemaAccessor` 实例。 | +| `DBTableEditorFactory.java` | 实现 `buildForSqlServer()`,返回 `SqlServerTableEditor` 实例。 | +| `DBObjectOperatorFactory.java` | 实现 `buildForSqlServer()`,返回 `SqlServerObjectOperator` 实例。 | +| `DBFunctionTemplateFactory.java` | 实现 `buildForSqlServer()`,返回 `SqlServerFunctionTemplate` 实例。 | + +### 5.2 `server/odc-core` 枚举与常量 + +| 文件路径 | 修改内容 | +| :--- | :--- | +| `DialectType.java` | 增加 `SQL_SERVER` 枚举值。 | +| `ConnectType.java` | 增加 `SQL_SERVER(DialectType.SQL_SERVER)` 枚举值。 | +| `OdcConstants.java` | 增加 `SQL_SERVER_DRIVER_CLASS_NAME` 和 `SQL_SERVER_DEFAULT_SCHEMA` 常量。 | +| `SqlCommentProcessor.java` | 在 `split()` 方法中增加对 `SQL_SERVER` 的处理逻辑。 | + +### 5.3 `server/odc-service` 业务集成 + +| 文件路径 | 修改内容 | +| :--- | :--- | +| `ConnectTypeUtil.java` | 在 `getConnectType()` 方法中增加对 `SQL_SERVER` 的识别逻辑。 | +| `ConnectionTesting.java` | 在 `test()` 方法中增加对 SQLServer 默认 Schema 的处理逻辑。 | +| `DruidDataSourceFactory.java` | 配置 SQLServer 特有的连接池参数(如 `validationQuery`)。 | + +### 5.4 `server/odc-migrate` 数据库初始化 + +| 文件路径 | 修改内容 | +| :--- | :--- | +| `R_2_0_0__initialize_version_diff_config.sql` | 增加 SQLServer 的版本差异配置(如 `column_data_type`、`support_view` 等)。 | + +--- + +## 6. 配置与注册 (插件层) + +1. **Plugin 注册**: + - 在插件模块的 `pom.xml` 中指定 `plugin.class`。 + - 在 `META-INF/MANIFEST.MF` 或通过注解确保 PF4J 能够识别插件。 + +--- + +## 7. 总结与原则 + +- **逻辑下沉**: 尽量在 `db-browser` 层实现方言逻辑,保持 `server/plugins` 层的轻量化。 +- **TDD 开发**: 优先编写单元测试,通过测试驱动方言适配的完善。 +- **解耦设计**: 避免在公共模块中编写特定数据库的业务代码,利用工厂模式和接口实现多数据库适配。 + +--- + +## 8. 待完善功能:SQL 语法解析器 (Parser) + +由于 SQL 语法解析(如 DDL 解析、SQL 检查)的实现成本较高,目前 SQLServer 插件暂未实现专用的语法解析器。如果后续需要支持如“影子表”、“回滚方案”或“SQL 检查”等深度依赖语法分析的功能,可参考以下路径进行实现: + +1. **定义 Antlr4 语法**: 在底层的 SQL 解析库中增加 SQLServer 的 Antlr4 语法文件。 +2. **实现插件层解析器**: + - **路径**: `server/plugins/schema-plugin-sqlserver/src/main/java/com/oceanbase/odc/plugin/schema/sqlserver/parser/` + - **操作**: 参照 `OBMySQLGetDBTableByParser.java`,实现 `SqlServerGetDBTableByParser`,通过语法树解析 DDL 字符串并还原为 `DBTable` 等模型对象。 +3. **集成到扩展点**: 将解析器集成到 `TableExtensionPoint` 等相关扩展点中,以支持通过 SQL 脚本反向生成元数据。 + From 4166a46eb2644bdfc806dc669cc05ae391fa9eec Mon Sep 17 00:00:00 2001 From: linxiaotao Date: Tue, 27 Jan 2026 10:29:07 +0000 Subject: [PATCH 3/4] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E7=8E=AF=E5=A2=83=E9=85=8D=E7=BD=AE=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/setup_system_how_to.md | 476 +++++++++++++++++++++++++++++++++++ docs/vscode_configuration.md | 462 ++++++++++++++++++++++++++++++++++ 2 files changed, 938 insertions(+) create mode 100644 docs/setup_system_how_to.md create mode 100644 docs/vscode_configuration.md diff --git a/docs/setup_system_how_to.md b/docs/setup_system_how_to.md new file mode 100644 index 0000000000..20f97c5123 --- /dev/null +++ b/docs/setup_system_how_to.md @@ -0,0 +1,476 @@ +# ODC 开发环境配置指南 - Cursor/VSCode + +本文档提供在 Cursor/VSCode 上配置和启动 ODC 后端项目的完整指南。 + +## 📋 目录 + +1. [环境要求](#环境要求) +2. [快速开始](#快速开始) +3. [详细配置步骤](#详细配置步骤) +4. [常见问题解决](#常见问题解决) +5. [验证和测试](#验证和测试) + +--- + +## 环境要求 + +### 必需环境 +- **Java 8**:用于项目编译和运行 +- **Java 21**:用于 Java Language Server(IDE 功能) +- **Maven**:项目使用 Maven Wrapper(`mvnw`),无需单独安装 +- **MySQL 8.0+**:用于元数据库 +- **Node.js 16+**(可选):仅当需要构建前端资源时 + +### IDE 扩展 +- **Extension Pack for Java**(Cursor/VSCode Java 扩展包) + +--- + +## 快速开始 + +### 一键启动(如果已完成所有配置) + +1. 按 `F5` 启动调试 +2. 选择 "Launch OdcServer" 配置 +3. 等待服务启动(约 1-2 分钟) +4. 访问 `http://localhost:8989/` 验证 + +--- + +## 详细配置步骤 + +### 阶段一:基础环境准备 ✅ + +#### 1.1 配置 Java 环境 + +确保系统已安装 Java 8 和 Java 21: + +```bash +# 检查 Java 8(项目编译使用) +java -version # 应该显示 1.8.x + +# 检查 Java 21(Language Server 使用) +/usr/lib/jvm/java-21-openjdk-amd64/bin/java -version +``` + +#### 1.2 配置 Cursor/VSCode 设置 + +配置文件:`.vscode/settings.json` + +关键配置: +- `java.configuration.runtimes`:配置 Java 8 路径 +- `java.jdt.ls.java.home`:配置 Java 21 路径(Language Server 需要) +- `java.project.sourcePaths` 和 `java.project.referencedLibraries`:已移除(使用 Maven 标准识别) + +#### 1.3 创建启动配置 + +配置文件:`.vscode/launch.json` + +已配置: +- ✅ 主类:`com.oceanbase.odc.server.OdcServer` +- ✅ 端口:8989 +- ✅ 数据库环境变量 +- ✅ VM 参数(日志、插件路径等) + +#### 1.4 创建构建任务 + +配置文件:`.vscode/tasks.json` + +可用任务: +- `Build Libs`:构建依赖组件 +- `Build JAR`:构建完整 JAR 包 +- `Maven: Compile`:编译项目 +- `Build SQL Console (Frontend)`:构建前端资源 + +--- + +### 阶段二:项目构建(必需)✅ + +#### 2.1 构建依赖组件 + +```bash +./script/build_libs.sh +``` + +**作用**: +- 构建 `ob-sql-parser` 和 `db-browser` +- 安装 `pty4j` 和 `purejavacomm` 到本地 Maven 仓库 + +**状态**: ✅ 已完成 + +#### 2.2 编译整个项目 + +```bash +./mvnw clean compile -DskipTests +``` + +或使用 VSCode 任务:`Tasks: Run Task` -> `Maven: Compile` + +**状态**: ✅ 已完成 + +#### 2.3 构建完整 JAR 包 + +```bash +./script/build_jar.sh +``` + +或使用 VSCode 任务:`Tasks: Run Task` -> `Build JAR` + +**构建结果**: +- ✅ JAR 包:`server/odc-server/target/odc-server-4.3.4-SNAPSHOT-executable.jar` +- ✅ Plugins:`distribution/plugins/`(21 个插件 JAR) +- ✅ Starters:`distribution/starters/`(2 个 starter JAR) +- ✅ Modules:`distribution/modules/`(1 个 module JAR) + +**状态**: ✅ 已完成 + +--- + +### 阶段三:前端资源构建 ✅ + +#### 3.1 配置 Node.js 环境(如果未安装) + +```bash +./script/init_node_env.sh +``` + +**状态**: ✅ Node.js 16.14.0 已安装 + +#### 3.2 更新前端子模块 + +```bash +./script/update_submodule.sh +``` + +**状态**: ✅ 前端子模块已更新(client 目录已存在) + +#### 3.3 配置 npm/pnpm 镜像源(国内用户必需) + +```bash +# 配置 npm 镜像源 +npm config set registry https://registry.npmmirror.com + +# 配置 pnpm 镜像源 +/root/.nvs/default/bin/pnpm config set registry https://registry.npmmirror.com + +# 创建项目级配置 +cd client +echo "registry=https://registry.npmmirror.com" > .npmrc +``` + +**状态**: ✅ 已配置淘宝镜像源 + +#### 3.4 安装前端依赖 + +```bash +cd /root/ODC/odc/client +/root/.nvs/default/bin/pnpm install +``` + +**预计时间**: 5-10 分钟(使用国内源) + +**状态**: ✅ 已完成 + +#### 3.5 构建前端资源 + +```bash +/root/.nvs/default/bin/pnpm run build:odc +``` + +**预计时间**: 5-10 分钟 + +**状态**: ✅ 已完成 + +#### 3.6 复制文件到后端 + +```bash +cd /root/ODC/odc +mkdir -p server/odc-server/src/main/resources/static/ +rm -rf server/odc-server/src/main/resources/static/* +cp -r client/dist/renderer/* server/odc-server/src/main/resources/static/ + +# 验证 +ls -lh server/odc-server/src/main/resources/static/index.html +``` + +**状态**: ✅ 已完成 + +**验证结果**: +- ✅ `index.html` 已存在(12K) +- ✅ 所有静态资源文件已复制 + +--- + +### 阶段四:数据库配置 ✅ + +#### 4.1 配置 MySQL SQL 模式 + +**问题**:MySQL 8.0 严格模式会导致 TIMESTAMP 字段报错 + +**解决方案**:修改 MySQL SQL 模式(开发环境) + +```sql +-- 连接 MySQL +mysql -h 10.186.58.3 -P 3306 -u odc -p + +-- 全局修改 SQL 模式(移除 NO_ZERO_DATE 和 STRICT_TRANS_TABLES) +SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; + +-- 验证 +SELECT @@GLOBAL.sql_mode; +``` + +**状态**: ✅ 已解决 + +--- + +## 常见问题解决 + +### 问题 1:pty4j 依赖解析失败 + +**错误信息**: +``` +Could not resolve dependencies: org.jetbrains.pty4j:pty4j:jar:0.11.4 +``` + +**原因**:`pty4j` 和 `purejavacomm` 不在 Maven 中央仓库,需要手动安装 + +**解决方案**: +```bash +# 1. 执行构建脚本安装依赖 +./script/build_libs.sh + +# 2. 清理失败缓存 +rm -rf ~/.m2/repository/org/jetbrains/pty4j/ + +# 3. 重新构建 +./script/build_jar.sh +``` + +**状态**: ✅ 已解决 + +--- + +### 问题 2:MySQL TIMESTAMP 字段错误 + +**错误信息**: +``` +Invalid default value for 'gmt_modify' +``` + +**原因**:MySQL 8.0 严格模式要求 TIMESTAMP 字段必须有默认值 + +**解决方案**:修改 MySQL SQL 模式(见阶段四) + +**状态**: ✅ 已解决 + +--- + +### 问题 3:pnpm corepack 错误 + +**错误信息**: +``` +Error: globalThis.fetch is not a function +``` + +**原因**:Node.js 16.14.0 通过 corepack 调用 pnpm 时,corepack 使用了不支持的 API + +**解决方案**: +```bash +# 方法 1:使用 npm 安装的 pnpm 完整路径 +/root/.nvs/default/bin/pnpm install + +# 方法 2:使用 npx(推荐) +npx pnpm@8 install + +# 方法 3:禁用 corepack +corepack disable +``` + +**状态**: ✅ 已解决(使用完整路径) + +--- + +### 问题 4:前端资源下载慢 + +**问题**:`pnpm install` 从官方源下载很慢 + +**解决方案**:配置国内镜像源(见阶段三 3.3) + +**状态**: ✅ 已解决 + +--- + +### 问题 5:前端页面模板错误 + +**错误信息**: +``` +Error resolving template [index], template might not exist +``` + +**原因**:前端资源未构建或未复制到后端 + +**解决方案**: +1. 构建前端资源(见阶段三) +2. 确保 `ODC_INDEX_PAGE_URI` 为空(使用本地资源) +3. 重启 ODC 服务 + +**状态**: ✅ 已解决 + +--- + +## 验证和测试 + +### 5.1 验证构建结果 + +```bash +# 检查 JAR 包 +ls -lh server/odc-server/target/odc-server-*-executable.jar + +# 检查插件和启动器 +ls -la distribution/plugins/ | wc -l # 应该显示 21+ +ls -la distribution/starters/ | wc -l # 应该显示 2+ + +# 检查前端资源 +ls -lh server/odc-server/src/main/resources/static/index.html +``` + +### 5.2 启动 ODC 服务 + +1. **在 Cursor 中启动**: + - 按 `F5` 或点击调试按钮 + - 选择 "Launch OdcServer" 配置 + - 等待服务启动(查看控制台输出) + +2. **验证启动日志**: + - 查看 `log/odc.log` 文件 + - 确认看到:`Tomcat started on port(s): 8989` + - 确认看到:`Started OdcServer in XX seconds` + +### 5.3 验证服务可用性 + +```bash +# 健康检查 +curl http://localhost:8989/api/v1/heartbeat/isHealthy + +# 应该返回:{"code":null,"data":true,...} +``` + +### 5.4 验证前端页面 + +访问以下地址,应该能看到 ODC 登录页面: + +- `http://localhost:8989/` +- `http://localhost:8989/index.html` +- `http://10.186.58.4:8989/`(如果从其他机器访问) + +--- + +## 当前配置状态 + +### ✅ 已完成 + +1. **基础环境** + - ✅ Java 8 和 Java 21 已配置 + - ✅ Cursor/VSCode 配置已完成 + - ✅ 启动配置已创建 + +2. **项目构建** + - ✅ 依赖组件已构建 + - ✅ 项目已编译 + - ✅ JAR 包已生成 + +3. **前端资源** + - ✅ Node.js 环境已配置 + - ✅ 前端依赖已安装 + - ✅ 前端资源已构建 + - ✅ 文件已复制到后端 + +4. **数据库配置** + - ✅ MySQL SQL 模式已调整 + - ✅ 数据库连接配置已设置 + +### 📝 当前配置 + +**数据库配置**(`.vscode/launch.json`): +- `ODC_DATABASE_HOST`: 10.186.58.3 +- `ODC_DATABASE_PORT`: 33060 +- `ODC_DATABASE_NAME`: odc_metadb +- `ODC_DATABASE_USERNAME`: odc +- `ODC_DATABASE_PASSWORD`: odcpass +- `ODC_PROFILE_MODE`: alipay +- `ODC_SERVER_PORT`: 8989 +- `ODC_INDEX_PAGE_URI`: ""(使用本地前端资源) + +--- + +## 下一步操作 + +### 日常开发 + +1. **启动服务**:按 `F5` 启动调试 +2. **查看日志**:`log/odc.log` +3. **访问前端**:`http://localhost:8989/` + +### 重新构建 + +如果修改了代码,需要重新编译: + +```bash +# 仅编译 +./mvnw compile -DskipTests + +# 完整构建(包括 JAR) +./script/build_jar.sh +``` + +### 前端资源更新 + +如果修改了前端代码: + +```bash +cd client +/root/.nvs/default/bin/pnpm run build:odc +cd .. +rm -rf server/odc-server/src/main/resources/static/* +cp -r client/dist/renderer/* server/odc-server/src/main/resources/static/ +``` + +--- + +## 注意事项 + +1. **构建顺序**: + - 必须先构建 libs → 然后编译项目 → 最后构建 JAR + +2. **数据库 SQL 模式**: + - 开发环境已调整 SQL 模式 + - 生产环境建议修复 SQL 脚本而不是修改数据库配置 + +3. **前端资源**: + - 如果只是后端开发,可以不构建前端 + - 可以通过 `ODC_INDEX_PAGE_URI` 环境变量引用远程前端资源 + +4. **Maven 源**: + - 如果下载依赖慢,可以配置阿里云镜像 + - 创建 `~/.m2/settings.xml` 配置镜像源 + +5. **端口冲突**: + - 默认端口 8989,可在 `launch.json` 中修改 + - 确保端口未被占用 + +--- + +## 参考文档 + +- [ODC 开发指南](../docs/zh-CN/DEVELOPER_GUIDE.md) +- [VSCode 配置说明](./README.md) + +--- + +## 更新记录 + +- **2026-01-13**:完成前端资源构建,文档整理完成 +- **2026-01-13**:解决 MySQL SQL 模式问题 +- **2026-01-13**:解决 pnpm corepack 问题 +- **2026-01-13**:完成项目构建和配置 diff --git a/docs/vscode_configuration.md b/docs/vscode_configuration.md new file mode 100644 index 0000000000..11654ea32d --- /dev/null +++ b/docs/vscode_configuration.md @@ -0,0 +1,462 @@ +# VSCode 开发环境配置文档 + +本文档包含 ODC 项目的 VSCode 开发环境完整配置说明。 + +## 目录结构 + +VSCode 配置文件位于 `.vscode/` 目录下,包含以下文件: + +- `settings.json` - 编辑器和工作区设置 +- `launch.json` - 调试和启动配置 +- `tasks.json` - 任务配置 +- `README.md` - 快速配置说明 + +--- + +## 1. settings.json + +编辑器和工作区设置配置文件。 + +```json +{ + "java.configuration.updateBuildConfiguration": "automatic", + "java.compile.nullAnalysis.mode": "automatic", + "java.import.maven.enabled": true, + "java.project.resourceFilters": ["node_modules", ".git"], + "java.configuration.runtimes": [ + { + "name": "JavaSE-1.8", + "path": "/usr/lib/jvm/java-8-openjdk-amd64", + "default": true + } + ], + "java.jdt.ls.java.home": "/usr/lib/jvm/java-21-openjdk-amd64", + "java.format.settings.url": "builds/code-style/eclipse-java-oceanbase-style.xml", + "java.format.settings.profile": "oceanbase-java-format", + "java.import.gradle.enabled": false, + "java.project.referencedLibraries": [ + "libs/**/*.jar" + ], + "files.eol": "\n", + "files.encoding": "utf8", + "files.exclude": { + "**/.factorypath": true + }, + "editor.formatOnSave": false, + "editor.codeActionsOnSave": { + "source.organizeImports": "never" + }, + "[java]": { + "editor.tabSize": 4, + "editor.insertSpaces": true + }, + "[xml]": { + "editor.tabSize": 4, + "editor.insertSpaces": true + }, + "[json]": { + "editor.tabSize": 2, + "editor.insertSpaces": true + }, + "[yaml]": { + "editor.tabSize": 2, + "editor.insertSpaces": true + }, + "java.debug.settings.onBuildFailureProceed": true, + "java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx4G -Xms100m -Xlog:disable", + "git.ignoreLimitWarning": true, + "java.project.sourcePaths": [ + "ci/script" + ] +} +``` + +### 配置说明 + +#### Java 配置 +- **自动构建配置更新**: `java.configuration.updateBuildConfiguration: "automatic"` +- **空值分析模式**: `java.compile.nullAnalysis.mode: "automatic"` +- **Maven 导入**: 已启用 +- **Gradle 导入**: 已禁用 +- **Java 运行时**: 配置了 Java 8 作为默认运行时,Java 21 作为 JDT Language Server 的运行时 +- **代码格式化**: 使用 OceanBase Java 代码风格配置文件 +- **引用库路径**: `libs/**/*.jar` + +#### 编辑器配置 +- **文件换行符**: LF (`\n`) +- **文件编码**: UTF-8 +- **保存时格式化**: 已禁用 +- **保存时组织导入**: 已禁用 + +#### 语言特定配置 +- **Java/XML**: Tab 大小为 4 空格 +- **JSON/YAML**: Tab 大小为 2 空格 + +#### JDT Language Server 配置 +- **JVM 参数**: 使用并行 GC,最大堆内存 4GB,初始堆内存 100MB + +--- + +## 2. launch.json + +调试和启动配置文件。 + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Launch OdcServer", + "request": "launch", + "mainClass": "com.oceanbase.odc.server.OdcServer", + "projectName": "odc-server", + "args": "--server.port=8989", + "vmArgs": "-XX:MaxRAMPercentage=45.0 -XX:InitialRAMPercentage=45.0 -XX:+UseG1GC -XX:+ExitOnOutOfMemoryError -Dlog4j.configurationFile=${workspaceFolder}/server/odc-server/target/classes/log4j2.xml -Dodc.log.directory=${workspaceFolder}/log -Duser.dir=${workspaceFolder} -Dplugin.dir=${workspaceFolder}/distribution/plugins -Dstarter.dir=${workspaceFolder}/distribution/starters", + "env": { + "ODC_DATABASE_HOST": "****", + "ODC_DATABASE_PORT": "33060", + "ODC_DATABASE_NAME": "odc_metadb", + "ODC_DATABASE_USERNAME": "****", + "ODC_DATABASE_PASSWORD": "****", + "ODC_PROFILE_MODE": "alipay", + "ODC_SERVER_PORT": "8989", + "ODC_INDEX_PAGE_URI": "", + "ODC_ADMIN_INITIAL_PASSWORD": "****" + }, + "console": "internalConsole", + "internalConsoleOptions": "openOnSessionStart" + }, + { + "type": "java", + "name": "Launch OdcServer (Remote Debug)", + "request": "attach", + "hostName": "localhost", + "port": 8000 + } + ] +} +``` + +### 配置说明 + +#### Launch OdcServer 配置 +- **类型**: Java 应用启动 +- **主类**: `com.oceanbase.odc.server.OdcServer` +- **项目名称**: `odc-server` +- **启动参数**: `--server.port=8989`(服务器端口) +- **JVM 参数**: + - 内存配置: 最大和初始 RAM 百分比为 45% + - GC 策略: G1GC + - OOM 处理: 内存溢出时退出 + - 日志配置: 使用 log4j2.xml + - 目录配置: 工作目录、日志目录、插件目录、启动器目录 + +- **环境变量**: + - `ODC_DATABASE_HOST`: 元数据库主机地址(已隐藏) + - `ODC_DATABASE_PORT`: 元数据库端口 `33060` + - `ODC_DATABASE_NAME`: 元数据库名称 `odc_metadb` + - `ODC_DATABASE_USERNAME`: 元数据库用户名(已隐藏) + - `ODC_DATABASE_PASSWORD`: 元数据库密码(已隐藏) + - `ODC_PROFILE_MODE`: Profile 模式 `alipay` + - `ODC_SERVER_PORT`: 服务器端口 `8989` + - `ODC_INDEX_PAGE_URI`: 前端静态资源地址(空字符串) + - `ODC_ADMIN_INITIAL_PASSWORD`: 管理员初始密码(已隐藏) + +#### Launch OdcServer (Remote Debug) 配置 +- **类型**: Java 远程调试附加 +- **主机**: `localhost` +- **端口**: `8000` + +### 环境变量配置建议 + +**注意**: 为了安全起见,建议将敏感信息(如数据库密码、IP 地址等)通过以下方式配置: + +1. **使用系统环境变量**(推荐): + ```bash + export ODC_DATABASE_HOST="your_host" + export ODC_DATABASE_PORT="33060" + export ODC_DATABASE_NAME="odc_metadb" + export ODC_DATABASE_USERNAME="your_username" + export ODC_DATABASE_PASSWORD="your_password" + export ODC_ADMIN_INITIAL_PASSWORD="your_admin_password" + ``` + +2. **使用 VSCode 环境变量文件**: 创建 `.env` 文件(需添加到 `.gitignore`) + +--- + +## 3. tasks.json + +任务配置文件,定义了常用的构建和测试任务。 + +```json +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build Libs", + "type": "shell", + "command": "./script/build_libs.sh", + "group": { + "kind": "build", + "isDefault": false + }, + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "Build JAR", + "type": "shell", + "command": "./script/build_jar.sh", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": "$tsc", + "dependsOn": "Build Libs" + }, + { + "label": "Maven: Clean Install", + "type": "shell", + "command": "./mvnw clean install -DskipTests", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": "$tsc" + }, + { + "label": "Maven: Compile", + "type": "shell", + "command": "./mvnw compile -DskipTests", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "shared", + "clear": false + }, + "problemMatcher": "$tsc" + }, + { + "label": "Init Node Environment", + "type": "shell", + "command": "./script/init_node_env.sh", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "Update Submodule", + "type": "shell", + "command": "./script/update_submodule.sh", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "Build SQL Console (Frontend)", + "type": "shell", + "command": "./script/build_sqlconsole.sh", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "Test: SQL Server Editors (db-browser)", + "type": "shell", + "command": "cd libs/db-browser && mvn test -Dtest=SqlServerColumnEditorTest,SqlServerConstraintEditorTest,SqlServerIndexEditorTest,SqlServerMViewEditorTest,SqlServerObjectOperatorTest,SqlServerPartitionEditorTest,SqlServerSequenceEditorTest,SqlServerSynonymEditorTest,SqlServerTableEditorTest,SqlServerTriggerEditorTest,SqlServerViewEditorTest -DskipTests=false", + "group": { + "kind": "test", + "isDefault": false + }, + "presentation": { + "reveal": "always", + "panel": "shared", + "clear": false + }, + "problemMatcher": "$tsc" + }, + { + "label": "Test: SQL Server SchemaAccessor (db-browser)", + "type": "shell", + "command": "cd libs/db-browser && mvn test -Dtest=SqlServerSchemaAccessorTest -DskipTests=false", + "group": { + "kind": "test", + "isDefault": false + }, + "presentation": { + "reveal": "always", + "panel": "shared", + "clear": false + }, + "problemMatcher": "$tsc" + }, + { + "label": "Test: SQL Server ViewTemplate (db-browser)", + "type": "shell", + "command": "cd libs/db-browser && mvn test -Dtest=SqlServerViewTemplateTest -DskipTests=false", + "group": { + "kind": "test", + "isDefault": false + }, + "presentation": { + "reveal": "always", + "panel": "shared", + "clear": false + }, + "problemMatcher": "$tsc" + } + ] +} +``` + +### 任务说明 + +#### 构建任务 + +1. **Build Libs** + - 构建依赖库 + - 命令: `./script/build_libs.sh` + - 使用方式: `Ctrl+Shift+P` -> `Tasks: Run Task` -> `Build Libs` + +2. **Build JAR** (默认构建任务) + - 构建 JAR 包 + - 命令: `./script/build_jar.sh` + - 依赖: Build Libs + - 使用方式: `Ctrl+Shift+B` 或 `Ctrl+Shift+P` -> `Tasks: Run Task` -> `Build JAR` + +3. **Maven: Clean Install** + - Maven 清理并安装(跳过测试) + - 命令: `./mvnw clean install -DskipTests` + +4. **Maven: Compile** + - Maven 编译(跳过测试) + - 命令: `./mvnw compile -DskipTests` + +5. **Init Node Environment** + - 初始化 Node.js 环境 + - 命令: `./script/init_node_env.sh` + +6. **Update Submodule** + - 更新 Git 子模块 + - 命令: `./script/update_submodule.sh` + +7. **Build SQL Console (Frontend)** + - 构建 SQL Console 前端 + - 命令: `./script/build_sqlconsole.sh` + +#### 测试任务 + +1. **Test: SQL Server Editors (db-browser)** + - 运行 SQL Server 编辑器相关测试 + - 测试类: ColumnEditor, ConstraintEditor, IndexEditor, MViewEditor, ObjectOperator, PartitionEditor, SequenceEditor, SynonymEditor, TableEditor, TriggerEditor, ViewEditor + +2. **Test: SQL Server SchemaAccessor (db-browser)** + - 运行 SQL Server SchemaAccessor 测试 + +3. **Test: SQL Server ViewTemplate (db-browser)** + - 运行 SQL Server ViewTemplate 测试 + +### 使用方式 + +- **运行任务**: `Ctrl+Shift+P` -> `Tasks: Run Task` -> 选择任务名称 +- **默认构建**: `Ctrl+Shift+B`(运行 "Build JAR" 任务) + +--- + +## 4. 快速开始 + +### 首次设置 + +1. **初始化 Node 环境**: + ```bash + # 方式一:使用任务 + Ctrl+Shift+P -> Tasks: Run Task -> Init Node Environment + + # 方式二:命令行 + ./script/init_node_env.sh + ``` + +2. **更新子模块**: + ```bash + Ctrl+Shift+P -> Tasks: Run Task -> Update Submodule + ``` + +3. **构建依赖库**: + ```bash + Ctrl+Shift+P -> Tasks: Run Task -> Build Libs + ``` + +4. **构建项目**: + ```bash + Ctrl+Shift+B # 或使用任务 "Build JAR" + ``` + +### 启动开发服务器 + +1. **配置环境变量**(如果未在 launch.json 中配置): + - 在系统环境变量中设置数据库连接信息 + - 或在 `launch.json` 的 `env` 部分配置(不推荐,会暴露敏感信息) + +2. **启动 ODC Server**: + - 按 `F5` 或点击调试按钮 + - 选择 "Launch OdcServer" 配置 + - 服务器将在 `http://localhost:8989` 启动 + +### 远程调试 + +1. 确保远程服务器已启动并监听 8000 端口 +2. 在 VSCode 中选择 "Launch OdcServer (Remote Debug)" 配置 +3. 按 `F5` 开始远程调试 + +--- + +## 5. 注意事项 + +1. **敏感信息保护**: + - 不要在 `launch.json` 中直接硬编码密码、IP 地址等敏感信息 + - 建议使用系统环境变量或 `.env` 文件(需添加到 `.gitignore`) + +2. **Java 版本要求**: + - 项目使用 Java 8 作为运行时 + - JDT Language Server 使用 Java 21 + +3. **内存配置**: + - JDT Language Server 最大堆内存为 4GB + - ODC Server 运行时内存为最大 RAM 的 45% + +4. **端口配置**: + - 默认服务器端口: `8989` + - 远程调试端口: `8000` + - 可通过 `args` 参数或环境变量 `ODC_SERVER_PORT` 修改 + +5. **代码格式化**: + - 保存时自动格式化已禁用 + - 使用 OceanBase Java 代码风格配置文件 + - 可通过 `Ctrl+Shift+P` -> `Format Document` 手动格式化 + +--- + +## 6. 相关文档 + +- [系统设置指南](./setup_system_how_to.md) +- [添加新插件指南](./add_a_new_plugin_how_to.md) +- [清理构建指南](./clean_build.md) From 68191d9f7de27de007b721fc0b6ea0657bfab397 Mon Sep 17 00:00:00 2001 From: linxiaotao Date: Tue, 27 Jan 2026 10:30:00 +0000 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85=E5=BD=93?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E7=9A=84=E8=AE=BE=E8=AE=A1=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designs/api/list-database-objects-flow.md | 102 ++++++++++++++++++ .../designs/datasource-plugin-architecture.md | 60 +++++++++++ docs/designs/odc-server-architecture.md | 54 ++++++++++ 3 files changed, 216 insertions(+) create mode 100644 docs/designs/api/list-database-objects-flow.md create mode 100644 docs/designs/datasource-plugin-architecture.md create mode 100644 docs/designs/odc-server-architecture.md diff --git a/docs/designs/api/list-database-objects-flow.md b/docs/designs/api/list-database-objects-flow.md new file mode 100644 index 0000000000..9db2af01b8 --- /dev/null +++ b/docs/designs/api/list-database-objects-flow.md @@ -0,0 +1,102 @@ +# listDatabaseObjects 接口流程图 + +```mermaid +flowchart TD + Start([接收请求
GET /api/v2/database/object/objects]) --> BuildParams[构建 QueryDBObjectParams] + BuildParams --> CheckSearchKey{searchKey 是否为空?} + CheckSearchKey -->|是| ReturnEmpty[返回空响应] + CheckSearchKey -->|否| ValidateParams{projectId 和
datasourceId 是否
同时设置?} + + ValidateParams -->|是| ThrowError1[抛出异常:
不能同时设置] + ValidateParams -->|否| CheckProjectId{projectId
是否不为空?} + + CheckProjectId -->|是| CheckProjectPermission[检查项目权限] + CheckProjectPermission --> CheckDatabaseIds1{databaseIds
是否不为空?} + CheckDatabaseIds1 -->|是| ValidateDatabases[验证数据库属于项目] + ValidateDatabases --> AddProjectDBIds[添加数据库ID到
queryDatabaseIds] + CheckDatabaseIds1 -->|否| GetProjectDBIds[获取项目下所有
数据库ID] + GetProjectDBIds --> AddProjectDBIds + + CheckProjectId -->|否| CheckDatasourceId{datasourceId
是否不为空?} + CheckDatasourceId -->|否| ThrowError2[抛出异常:
projectId 或 datasourceId 必填] + CheckDatasourceId -->|是| GetDatabasesByConnection[获取数据源下的数据库] + GetDatabasesByConnection --> CheckOrgType{组织类型?} + + CheckOrgType -->|个人| CheckCreator[检查是否为创建者] + CheckCreator -->|否| ThrowError3[抛出异常:
连接不存在] + CheckCreator -->|是| CheckDatabaseIds2{databaseIds
是否不为空?} + CheckDatabaseIds2 -->|是| FilterDBIds1[过滤数据库ID] + CheckDatabaseIds2 -->|否| AddAllDBIds1[添加所有数据库ID] + FilterDBIds1 --> AddDatasourceDBIds[添加数据库ID到
queryDatabaseIds] + AddAllDBIds1 --> AddDatasourceDBIds + + CheckOrgType -->|团队| GetProjectIds[获取用户所属项目ID] + GetProjectIds --> CheckDatabaseIds3{databaseIds
是否不为空?} + CheckDatabaseIds3 -->|是| FilterDBIds2[过滤:数据库存在且
属于用户项目] + CheckDatabaseIds3 -->|否| FilterAllDBIds[过滤所有数据库:
属于用户项目] + FilterDBIds2 --> AddDatasourceDBIds + FilterAllDBIds --> AddDatasourceDBIds + + AddProjectDBIds --> CheckEmpty{queryDatabaseIds
是否为空?} + AddDatasourceDBIds --> CheckEmpty + CheckEmpty -->|是| ReturnEmpty + CheckEmpty -->|否| GetDatabaseDetails[获取数据库详情] + + GetDatabaseDetails --> CheckTypes1{types 为空或
包含 SCHEMA?} + CheckTypes1 -->|是| SearchSchemas[搜索数据库名称
匹配 searchKey] + SearchSchemas --> SortSchemas[按名称长度和名称排序
取前 MAX_RETURN_SIZE_PER_TYPE] + SortSchemas --> SetDatabases[设置响应中的 databases] + CheckTypes1 -->|否| CheckTypes2{types 为空或
包含 COLUMN?} + SetDatabases --> CheckTypes2 + + CheckTypes2 -->|是| SearchColumns[搜索列名称
匹配 searchKey] + SearchColumns --> SortColumns[按名称长度和名称排序
取前 MAX_RETURN_SIZE_PER_TYPE] + SortColumns --> GetObjectIds[获取列关联的对象ID] + GetObjectIds --> GetObjects[查询对象实体] + GetObjects --> SetColumns[设置响应中的 dbColumns] + CheckTypes2 -->|否| SearchDBObjects + + SetColumns --> SearchDBObjects[搜索数据库对象
匹配 searchKey] + SearchDBObjects --> FilterByTypes{types 是否
不为空?} + FilterByTypes -->|是| AddTypeFilter[添加类型过滤条件] + FilterByTypes -->|否| QueryObjects[查询对象实体] + AddTypeFilter --> QueryObjects + + QueryObjects --> GroupByType[按类型分组] + GroupByType --> SortObjects[按名称长度和名称排序
每种类型取前 MAX_RETURN_SIZE_PER_TYPE] + SortObjects --> SetDBObjects[设置响应中的 dbObjects] + SetDBObjects --> ReturnResponse[返回响应] + ReturnEmpty --> ReturnResponse + ReturnResponse --> End([结束]) + + style Start fill:#1e3a8a,stroke:#1e40af,stroke-width:3px,color:#ffffff + style End fill:#1e3a8a,stroke:#1e40af,stroke-width:3px,color:#ffffff + style ReturnEmpty fill:#dc2626,stroke:#b91c1c,stroke-width:2px,color:#ffffff + style ThrowError1 fill:#dc2626,stroke:#b91c1c,stroke-width:2px,color:#ffffff + style ThrowError2 fill:#dc2626,stroke:#b91c1c,stroke-width:2px,color:#ffffff + style ThrowError3 fill:#dc2626,stroke:#b91c1c,stroke-width:2px,color:#ffffff + style CheckSearchKey fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style ValidateParams fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckProjectId fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckDatasourceId fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckDatabaseIds1 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckDatabaseIds2 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckDatabaseIds3 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckOrgType fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckEmpty fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckTypes1 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style CheckTypes2 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style FilterByTypes fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000000 + style BuildParams fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#ffffff + style CheckProjectPermission fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#ffffff + style ValidateDatabases fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#ffffff + style GetProjectDBIds fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#ffffff + style GetDatabasesByConnection fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#ffffff + style CheckCreator fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#ffffff + style GetProjectIds fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#ffffff + style GetDatabaseDetails fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#ffffff + style SearchSchemas fill:#10b981,stroke:#059669,stroke-width:2px,color:#ffffff + style SearchColumns fill:#10b981,stroke:#059669,stroke-width:2px,color:#ffffff + style SearchDBObjects fill:#10b981,stroke:#059669,stroke-width:2px,color:#ffffff + style ReturnResponse fill:#10b981,stroke:#059669,stroke-width:2px,color:#ffffff +``` diff --git a/docs/designs/datasource-plugin-architecture.md b/docs/designs/datasource-plugin-architecture.md new file mode 100644 index 0000000000..7c8103c788 --- /dev/null +++ b/docs/designs/datasource-plugin-architecture.md @@ -0,0 +1,60 @@ +# 数据源插件扩展架构 + +```mermaid +graph TB + subgraph "Plugin Discovery" + A[PluginService
启动时加载插件] + B[PF4J PluginManager
插件管理器] + C[PluginFinder
插件查找器] + end + + subgraph "Extension Points" + D[ConnectionExtensionPoint
连接扩展点] + E[SessionExtensionPoint
会话扩展点] + F[SchemaExtensionPoint
Schema扩展点] + end + + subgraph "Plugin Implementation" + G[SqlServerConnectionExtension
generateJdbcUrl
getDriverClassName
test] + H[SqlServerSessionExtension
switchSchema
getCurrentSchema
getConnectionId] + I[SqlServerSchemaExtension
list/getDetail] + end + + subgraph "Plugin Usage" + J[ConnectionPluginUtil
getConnectionExtension
getSessionExtension] + K[ConnectionSessionFactory
创建会话] + L[OBConsoleDataSourceFactory
创建数据源] + end + + A --> B + B --> C + C --> D + C --> E + C --> F + D --> G + E --> H + F --> I + J --> D + J --> E + K --> J + L --> J +``` + +## 扩展方法 + +1. **实现 ConnectionExtensionPoint** + - generateJdbcUrl: 生成 JDBC URL + - getDriverClassName: 返回驱动类名 + - test: 测试连接 + - getConnectionInitializers: 连接初始化器 + +2. **实现 SessionExtensionPoint** + - switchSchema: 切换Schema + - getCurrentSchema: 获取当前Schema + - getConnectionId: 获取连接ID + - getVariable: 获取变量值 + +3. **注册插件** + - 使用 @Extension 注解 + - 在 plugin.properties 中声明 DialectType + - 插件JAR放入 distribution/plugins 目录 diff --git a/docs/designs/odc-server-architecture.md b/docs/designs/odc-server-architecture.md new file mode 100644 index 0000000000..ed8e920b16 --- /dev/null +++ b/docs/designs/odc-server-architecture.md @@ -0,0 +1,54 @@ +# ODC Server 整体架构 + +```mermaid +graph TB + subgraph "Web Layer" + A[odc-server
REST API & WebSocket] + end + + subgraph "Business Layer" + B[odc-service
业务逻辑实现] + end + + subgraph "Core Framework" + C[odc-core
核心框架] + end + + subgraph "Plugin System" + D[PluginService
插件管理器] + E[connect-plugin-api
连接插件接口] + F[schema-plugin-api
Schema插件接口] + G[task-plugin-api
任务插件接口] + H[connect-plugin-sqlserver
SQL Server实现] + I[connect-plugin-mysql
MySQL实现] + J[connect-plugin-ob-mysql
OB MySQL实现] + end + + subgraph "Data Source" + K[ConnectionSession
连接会话] + L[DataSourceFactory
数据源工厂] + M[JDBC Connection
数据库连接] + end + + subgraph "SQL Execution" + N[OdcStatementCallBack
SQL执行回调] + O[Statement.execute
执行SQL] + P[JdbcGeneralResult
执行结果] + end + + A --> B + B --> C + B --> D + D --> E + D --> F + D --> G + E --> H + E --> I + E --> J + B --> K + K --> L + L --> M + K --> N + N --> O + O --> P +```