Metadata-Version: 2.4
Name: dm-pure
Version: 1.0.0
Summary: 纯 Python 实现的达梦 DM8 数据库驱动（无 native 依赖）
Author: dm-pure
License: MIT
Keywords: dameng,dm8,database,driver,纯Python
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: ==3.10.*
Description-Content-Type: text/markdown

# dm-pure：纯 Python 达梦 DM8 数据库驱动

零 native 依赖、100% Python 实现的达梦数据库驱动。支持达梦 DM8 常用功能，适合受限环境（无编译工具/无法加载 native 库的机器）。

## 特性

- ✅ 连接：DH 密钥交换 + DES-CFB 加密登录（内置纯 Python 加密，零依赖）
- ✅ 查询：SELECT / INSERT / UPDATE / DELETE，支持参数绑定（含 NULL）
- ✅ 类型：INT / BIGINT / DECIMAL / DATE / TIME / DATETIME / FLOAT / 中文（GB18030）等
- ✅ 大结果集：分批 fetch（cmd=7）
- ✅ LOB：CLOB / BLOB 读写（含大 LOB 分段传输）
- ✅ 事务：begin / commit / rollback / 隔离级别
- ✅ 存储过程：CALL + IN/OUT 参数
- ✅ 批量插入：executemany（协议级 batch）
- ✅ 连接池：线程安全，自动重连
- ✅ DB-API 2.0 兼容层：惰性游标（fetchone/fetchmany/fetchall 按需拉取）
- ✅ 健壮性：超时控制、断线重连、错误码表

## 安装

```bash
pip install dm-pure
```

**零依赖**：加密算法（DES/AES/RC4）内置纯 Python 实现。若环境已安装 pycryptodome 会自动优先使用（性能更优），否则用内置实现，功能完全一致。

## 快速上手

### 底层 API

```python
from dmpy import DMClient

c = DMClient("127.0.0.1", 5236, "SYSDBA", "password")
c.connect()
c.execute("SELECT id, name FROM t WHERE id = ?", [1])     # → (cols, rows)
c.execute("INSERT INTO t VALUES (?, ?)", [1, "x"])        # → (None, 影响行数)
c.begin(); c.execute(...); c.commit()                     # 事务
c.close()
```

### DB-API 2.0（sqlite3/pymysql 风格）

```python
import dmpy.dbapi as dm

conn = dm.connect(host="127.0.0.1", port=5236, user="SYSDBA", password="...")
cur = conn.cursor()
cur.execute("SELECT id, name FROM t WHERE id >= ?", [1])
rows = cur.fetchall()          # 大结果集自动分批拉取
cur.executemany("INSERT INTO t VALUES (?, ?)", [[1, "a"], [2, "b"]])
conn.commit()
conn.close()
```

### 存储过程

```python
from dmpy import DMClient, OUT

c = DMClient("127.0.0.1", 5236, "SYSDBA", "password")
c.connect()
r = c.execute("CALL sp_test(?, ?, ?, ?)", [5, "hello", OUT(int), OUT(str)])
print(r[2])  # → [10, "hello"]（OUT 参数返回值）
```

### 连接池

```python
from dmpy.pool import ConnectionPool

pool = ConnectionPool(host="127.0.0.1", port=5236, user="SYSDBA", password="...",
                      min_connections=2, max_connections=10)
with pool.connection() as conn:
    cur = conn.cursor()
    cur.execute("SELECT 1")
pool.close()
```

### 大 LOB

```python
# 写入 1MB CLOB/BLOB（自动分段传输）
c.execute("INSERT INTO t (id, content, data) VALUES (?, ?, ?)",
          [1, "大文本..." * 50000, b"\x00\x01..." * 100000])
# 读取（自动完整拉取）
rows = c.execute("SELECT content, data FROM t WHERE id = ?", [1])[1]
```

## 项目结构

```
dmpy/
├── client.py       # 核心：连接/查询/参数绑定/LOB/事务/存储过程/惰性查询
├── crypto.py       # 加密（内置纯 Python + 可选 pycryptodome）
├── _pure_crypto.py # 纯 Python DES/AES/RC4 实现
├── frame.py        # 协议帧封装/解析
├── result.py       # 列描述符/行数据/类型解码
├── dbapi.py        # DB-API 2.0 兼容层
└── pool.py         # 连接池
```

## 环境要求

- Python >= 3.8
- 可达的达梦 DM8 服务器（TCP 5236 端口）

## 测试

```bash
python test_all.py   # 22 项回归断言（需可达的达梦服务器，修改 test_all.py 中的连接参数）
```

## 发布

发布到 PyPI 的流程见 [PUBLISHING.md](PUBLISHING.md)。
