Skip to content

Commit 8f660d3

Browse files
committed
开源合规调整:移除专有头文件分发,添加 CI 构建 macOS wheel
- 新增 .gitignore,排除 dpi_include/ 等构建产物 - setup.py: 硬编码路径改为 find_dpi_include() 查找链(本地 > DM_HOME) - 修正 license 为 MulanPSL-2.0(与 LICENSE 文件一致) - MANIFEST.in: 移除 dpi_include 头文件分发 - Makefile: 添加 dpi-headers-secret 目标 - 新增 GitHub Actions CI:macOS ARM64/x86_64 × Python 3.9-3.13
1 parent bca676b commit 8f660d3

9 files changed

Lines changed: 623 additions & 487 deletions

File tree

.github/workflows/build-wheels.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Build macOS wheels
2+
3+
on:
4+
push:
5+
tags: ["v*"]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
jobs:
11+
build:
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
include:
16+
- runner: macos-14
17+
arch: arm64
18+
- runner: macos-13
19+
arch: x86_64
20+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
21+
22+
runs-on: ${{ matrix.runner }}
23+
name: "${{ matrix.arch }} — Python ${{ matrix.python-version }}"
24+
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
- uses: actions/setup-go@v5
29+
with:
30+
go-version: "1.21"
31+
32+
- uses: actions/setup-python@v5
33+
with:
34+
python-version: ${{ matrix.python-version }}
35+
36+
- name: Decode DPI headers
37+
env:
38+
DPI_HEADERS_TAR_B64: ${{ secrets.DPI_HEADERS_TAR_B64 }}
39+
run: |
40+
mkdir -p dpi_include
41+
echo "$DPI_HEADERS_TAR_B64" | base64 -d | tar xzf - -C dpi_include/
42+
43+
- name: Build Go bridge library
44+
run: |
45+
cd dpi_bridge && go build -buildmode=c-shared -o libdmdpi.dylib .
46+
install_name_tool -id @rpath/libdmdpi.dylib libdmdpi.dylib
47+
48+
- name: Install build tools
49+
run: pip install build delocate
50+
51+
- name: Build wheel
52+
run: DMPYTHON_SKIP_GO_BUILD=1 python -m build --wheel
53+
54+
- name: Delocate wheel
55+
run: |
56+
mkdir -p dist_fixed
57+
DYLD_LIBRARY_PATH=dpi_bridge delocate-wheel -w dist_fixed dist/*.whl -v
58+
59+
- name: Verify wheel
60+
run: |
61+
python -m venv /tmp/test_venv
62+
/tmp/test_venv/bin/pip install dist_fixed/*.whl
63+
/tmp/test_venv/bin/python -c "import dmPython; print('dmPython version:', dmPython.version)"
64+
65+
- uses: actions/upload-artifact@v4
66+
with:
67+
name: wheel-${{ matrix.arch }}-py${{ matrix.python-version }}
68+
path: dist_fixed/*.whl
69+
70+
release:
71+
needs: build
72+
if: startsWith(github.ref, 'refs/tags/v')
73+
runs-on: macos-14
74+
permissions:
75+
contents: write
76+
77+
steps:
78+
- uses: actions/download-artifact@v4
79+
with:
80+
path: dist_fixed
81+
pattern: wheel-*
82+
merge-multiple: true
83+
84+
- name: Create GitHub Release
85+
env:
86+
GH_TOKEN: ${{ github.token }}
87+
TAG_NAME: ${{ github.ref_name }}
88+
run: gh release create "$TAG_NAME" --generate-notes dist_fixed/*.whl

.gitignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# DPI headers (proprietary, not distributed)
2+
dpi_include/
3+
4+
# Build artifacts
5+
build/
6+
dist/
7+
dist_fixed/
8+
*.egg-info/
9+
*.so
10+
*.dylib
11+
12+
# Go bridge output
13+
dpi_bridge/libdmdpi.dylib
14+
dpi_bridge/libdmdpi.h
15+
16+
# Environment
17+
.venv/
18+
.dm_home/
19+
__pycache__/
20+
21+
# IDE
22+
.idea/
23+
24+
# Trace log
25+
dmPython_trace.log

CLAUDE.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## 项目概述
6+
7+
dmPython 是达梦数据库(DM8)的原生 Python 驱动,遵循 Python DB API 2.0 规范。整个项目是一个 C 扩展模块,通过 DPI(Dameng Programming Interface)库与达梦数据库通信。当前版本 2.5.30,支持 Python 2.7 及 3.x(含 3.12+),支持 sqlalchemy 和 django 框架。
8+
9+
## 构建与安装
10+
11+
**前置条件:** 需设置 `DM_HOME` 环境变量指向达梦安装目录或 drivers 目录,该路径下必须有 `include``dpi/include` 目录。
12+
13+
```bash
14+
# 设置环境变量
15+
export DM_HOME=/opt/dmdbms # 或 /drivers,具体以实际环境为准
16+
17+
# 源码安装
18+
python setup.py install
19+
20+
# 仅编译
21+
python setup.py build
22+
23+
# 运行测试(需要 test/ 目录下有 test.py/test3k.py)
24+
python setup.py test
25+
26+
# 生成平台安装包
27+
python setup.py bdist_rpm # Linux RPM
28+
python setup.py bdist_wininst # Windows
29+
```
30+
31+
**运行时依赖:** 需要 DPI 动态库(Linux: `libdmdpi.so`,Windows: `dmdpi.dll`,macOS: `libdmdpi`),通过 `LD_LIBRARY_PATH``PATH` 指向 DPI 所在目录。
32+
33+
**达梦版本:** 默认 8.1,可通过 `DM_VER` 环境变量覆盖。
34+
35+
**调试追踪:** 取消 `setup.py``defineMacros.append(('TRACE', None))` 的注释即可在当前目录生成 `dmPython_trace.log`
36+
37+
## 代码架构
38+
39+
所有源码(C/H 文件)位于项目根目录,无子目录结构。
40+
41+
### 核心层次
42+
43+
1. **模块入口**`py_Dameng.c` / `py_Dameng.h`
44+
- Python 模块初始化,注册所有类型对象和 DB API 2.0 异常层次(Warning, Error, InterfaceError, DatabaseError 等)
45+
46+
2. **核心结构定义**`strct.h`
47+
- `dm_Environment`:DPI 环境句柄、编码信息
48+
- `dm_Connection`:连接句柄、连接参数、事务设置、类型处理器
49+
- `dm_Cursor`:语句句柄、列/参数描述符、变量绑定、行计数器
50+
51+
3. **连接管理**`Connection.c`
52+
- 连接建立/关闭、属性读写(autocommit、timeout、隔离级别等)
53+
- 支持 shutdown 模式:ABORT、IMMEDIATE、TRANSACTIONAL、NORMAL
54+
55+
4. **游标操作**`Cursor.c`(最大文件)
56+
- SQL 执行、参数绑定、结果集获取、批量操作
57+
- 支持 TUPLE_CURSOR (0) 和 DICT_CURSOR (1) 两种模式
58+
59+
5. **行对象**`row.c` / `row.h`
60+
- 类元组的结果行,支持列名到索引的映射
61+
62+
6. **环境/错误/缓冲**`Environment.c`, `Error.c`, `Buffer.c`
63+
64+
### 变量类型系统
65+
66+
核心接口定义在 `var_pub.h`,类型调度通过 `dm_VarType` 结构体中的函数指针表实现(initializeProc, finalizeProc, setValueProc, getValueProc 等)。
67+
68+
- `var.c` — 变量管理和类型选择的核心逻辑
69+
- `vString.c` — 字符串/varchar 处理
70+
- `vNumber.c` — 数值类型转换(integer, bigint, float, double, decimal)
71+
- `vDateTime.c` — 日期、时间、时间戳、时区
72+
- `vInterval.c` — 间隔类型
73+
- `vLob.c` — BLOB/CLOB 读写
74+
- `vBfile.c` — BFILE(外部文件)
75+
- `vCursor.c` — 嵌套游标
76+
- `vObject.c` — 对象和记录类型
77+
- `vlong.c` — 长二进制/长字符串
78+
79+
### 外部对象封装
80+
81+
- `exLob.c` — 外部 LOB 接口(读写/截断操作)
82+
- `exObject.c` — 外部对象接口(属性访问)
83+
- `exBfile.c` — 外部 BFILE 接口
84+
- `tObject.c` — 对象类型元数据
85+
- `trc.c` — 调试追踪工具
86+
87+
## 关键常量
88+
89+
```c
90+
#define MAX_STRING_CHARS 4094
91+
#define MAX_BINARY_BYTES 8188
92+
#define NAMELEN 128
93+
#define PY_SQL_MAX_LEN 0x8000
94+
```
95+
96+
## 编码注意事项
97+
98+
- 64 位平台自动定义 `DM64` 宏(`setup.py` 中根据 `struct.calcsize("P")` 判断)
99+
- Windows 平台定义 `WIN32` 和 `_CRT_SECURE_NO_WARNINGS`
100+
- 构建 dmPython 的环境 UCS 编码需与运行环境一致,否则会出现 `undefined symbol: PyUnicodeUCS2_Format` 错误
101+
- Python 3.12+ 使用 setuptools 替代 distutils

0 commit comments

Comments
 (0)