@h-ai/reldb 0.1.0-alpha8 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,295 +1,14 @@
1
- import { z } from 'zod';
1
+ import { DbType, ReldbConfigInput, ReldbConfig } from './schemas.js';
2
+ export { MysqlConfig, MysqlConfigSchema, MysqlOptionsSchema, MysqlPoolConfig, MysqlPoolConfigSchema, MysqlSslConfigSchema, PoolConfig, PoolConfigSchema, PostgresqlConfig, PostgresqlConfigSchema, ReldbConfigSchema, ReldbOperationLogConfig, ReldbOperationLogConfigSchema, ReldbTypeSchema, SqliteConfig, SqliteConfigSchema, SqliteOptionsSchema, SslConfig, SslConfigSchema } from './schemas.js';
2
3
  import * as _h_ai_core from '@h-ai/core';
3
4
  import { HaiResult, PaginationOptionsInput, PaginatedResult, PaginationOptions } from '@h-ai/core';
4
-
5
- /**
6
- * @h-ai/reldb — 数据库配置 Schema
7
- *
8
- * 本文件定义数据库模块的配置结构,使用 Zod 进行运行时校验。
9
- * @module reldb-config
10
- */
11
-
12
- /**
13
- * 数据库类型枚举
14
- *
15
- * 支持的数据库类型:
16
- * - `sqlite` - SQLite 嵌入式数据库(使用 better-sqlite3)
17
- * - `postgresql` - PostgreSQL 数据库(使用 pg)
18
- * - `mysql` - MySQL 数据库(使用 mysql2)
19
- */
20
- declare const ReldbTypeSchema: z.ZodEnum<{
21
- sqlite: "sqlite";
22
- postgresql: "postgresql";
23
- mysql: "mysql";
24
- }>;
25
- /** 数据库类型 */
26
- type DbType = z.infer<typeof ReldbTypeSchema>;
27
- /**
28
- * 连接池配置 Schema
29
- *
30
- * 用于 PostgreSQL 和 MySQL 的连接池管理。
31
- * SQLite 为嵌入式数据库,不使用连接池。
32
- *
33
- * @example
34
- * ```ts
35
- * const poolConfig = {
36
- * min: 2,
37
- * max: 20,
38
- * idleTimeout: 30000,
39
- * acquireTimeout: 10000
40
- * }
41
- * ```
42
- */
43
- declare const PoolConfigSchema: z.ZodObject<{
44
- min: z.ZodDefault<z.ZodNumber>;
45
- max: z.ZodDefault<z.ZodNumber>;
46
- idleTimeout: z.ZodDefault<z.ZodNumber>;
47
- acquireTimeout: z.ZodDefault<z.ZodNumber>;
48
- }, z.core.$strip>;
49
- /** 连接池配置类型 */
50
- type PoolConfig = z.infer<typeof PoolConfigSchema>;
51
- /**
52
- * SSL 配置 Schema
53
- *
54
- * 支持多种配置方式:
55
- * - `true/false` - 简单开关
56
- * - `'require'/'prefer'/'allow'/'disable'` - SSL 模式
57
- * - 自定义对象 - 详细 SSL 配置
58
- *
59
- * @example
60
- * ```ts
61
- * // 简单开关
62
- * ssl: true
63
- *
64
- * // SSL 模式
65
- * ssl: 'require'
66
- *
67
- * // 自定义配置
68
- * ssl: { rejectUnauthorized: false }
69
- * ```
70
- */
71
- declare const SslConfigSchema: z.ZodUnion<readonly [z.ZodBoolean, z.ZodEnum<{
72
- require: "require";
73
- prefer: "prefer";
74
- allow: "allow";
75
- disable: "disable";
76
- }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>;
77
- /** SSL 配置类型 */
78
- type SslConfig = z.infer<typeof SslConfigSchema>;
79
- /**
80
- * SQLite 特定选项 Schema
81
- *
82
- * @example
83
- * ```ts
84
- * sqlite: {
85
- * walMode: true, // 启用 WAL 模式,提高并发性能
86
- * readonly: false // 只读模式
87
- * }
88
- * ```
89
- */
90
- declare const SqliteOptionsSchema: z.ZodObject<{
91
- walMode: z.ZodDefault<z.ZodBoolean>;
92
- readonly: z.ZodDefault<z.ZodBoolean>;
93
- }, z.core.$strip>;
94
- /**
95
- * MySQL 特定选项 Schema
96
- *
97
- * @example
98
- * ```ts
99
- * mysql: {
100
- * charset: 'utf8mb4',
101
- * timezone: '+08:00'
102
- * }
103
- * ```
104
- */
105
- declare const MysqlOptionsSchema: z.ZodObject<{
106
- charset: z.ZodDefault<z.ZodString>;
107
- timezone: z.ZodOptional<z.ZodString>;
108
- }, z.core.$strip>;
109
- /**
110
- * SQLite 配置 Schema
111
- *
112
- * @example
113
- * ```ts
114
- * // 文件数据库
115
- * { type: 'sqlite', database: './data.db' }
116
- *
117
- * // 内存数据库(用于测试)
118
- * { type: 'sqlite', database: ':memory:' }
119
- * ```
120
- */
121
- declare const SqliteConfigSchema: z.ZodObject<{
122
- type: z.ZodLiteral<"sqlite">;
123
- database: z.ZodString;
124
- sqlite: z.ZodOptional<z.ZodObject<{
125
- walMode: z.ZodDefault<z.ZodBoolean>;
126
- readonly: z.ZodDefault<z.ZodBoolean>;
127
- }, z.core.$strip>>;
128
- }, z.core.$strip>;
129
- /**
130
- * PostgreSQL 配置 Schema
131
- *
132
- * @example
133
- * ```ts
134
- * // 使用连接字符串
135
- * { type: 'postgresql', url: 'postgres://user:pass@localhost:5432/mydb' }
136
- *
137
- * // 使用分开的字段
138
- * {
139
- * type: 'postgresql',
140
- * host: 'localhost',
141
- * port: 5432,
142
- * database: 'mydb',
143
- * user: 'admin',
144
- * password: 'secret',
145
- * pool: { max: 20 }
146
- * }
147
- * ```
148
- */
149
- declare const PostgresqlConfigSchema: z.ZodObject<{
150
- url: z.ZodOptional<z.ZodString>;
151
- host: z.ZodDefault<z.ZodString>;
152
- port: z.ZodOptional<z.ZodNumber>;
153
- database: z.ZodString;
154
- user: z.ZodOptional<z.ZodString>;
155
- password: z.ZodOptional<z.ZodString>;
156
- ssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodEnum<{
157
- require: "require";
158
- prefer: "prefer";
159
- allow: "allow";
160
- disable: "disable";
161
- }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
162
- pool: z.ZodOptional<z.ZodObject<{
163
- min: z.ZodDefault<z.ZodNumber>;
164
- max: z.ZodDefault<z.ZodNumber>;
165
- idleTimeout: z.ZodDefault<z.ZodNumber>;
166
- acquireTimeout: z.ZodDefault<z.ZodNumber>;
167
- }, z.core.$strip>>;
168
- type: z.ZodLiteral<"postgresql">;
169
- }, z.core.$strip>;
170
- /**
171
- * MySQL 配置 Schema
172
- *
173
- * @example
174
- * ```ts
175
- * // 使用连接字符串
176
- * { type: 'mysql', url: 'mysql://user:pass@localhost:3306/mydb' }
177
- *
178
- * // 使用分开的字段
179
- * {
180
- * type: 'mysql',
181
- * host: 'localhost',
182
- * port: 3306,
183
- * database: 'mydb',
184
- * user: 'admin',
185
- * password: 'secret',
186
- * mysql: { charset: 'utf8mb4' }
187
- * }
188
- * ```
189
- */
190
- declare const MysqlConfigSchema: z.ZodObject<{
191
- url: z.ZodOptional<z.ZodString>;
192
- host: z.ZodDefault<z.ZodString>;
193
- port: z.ZodOptional<z.ZodNumber>;
194
- database: z.ZodString;
195
- user: z.ZodOptional<z.ZodString>;
196
- password: z.ZodOptional<z.ZodString>;
197
- ssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodEnum<{
198
- require: "require";
199
- prefer: "prefer";
200
- allow: "allow";
201
- disable: "disable";
202
- }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
203
- pool: z.ZodOptional<z.ZodObject<{
204
- min: z.ZodDefault<z.ZodNumber>;
205
- max: z.ZodDefault<z.ZodNumber>;
206
- idleTimeout: z.ZodDefault<z.ZodNumber>;
207
- acquireTimeout: z.ZodDefault<z.ZodNumber>;
208
- }, z.core.$strip>>;
209
- type: z.ZodLiteral<"mysql">;
210
- mysql: z.ZodOptional<z.ZodObject<{
211
- charset: z.ZodDefault<z.ZodString>;
212
- timezone: z.ZodOptional<z.ZodString>;
213
- }, z.core.$strip>>;
214
- }, z.core.$strip>;
215
- /**
216
- * 统一数据库配置 Schema(判别联合体)
217
- *
218
- * 根据 `type` 字段区分不同数据库类型的配置。
219
- */
220
- declare const ReldbConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
221
- type: z.ZodLiteral<"sqlite">;
222
- database: z.ZodString;
223
- sqlite: z.ZodOptional<z.ZodObject<{
224
- walMode: z.ZodDefault<z.ZodBoolean>;
225
- readonly: z.ZodDefault<z.ZodBoolean>;
226
- }, z.core.$strip>>;
227
- }, z.core.$strip>, z.ZodObject<{
228
- url: z.ZodOptional<z.ZodString>;
229
- host: z.ZodDefault<z.ZodString>;
230
- port: z.ZodOptional<z.ZodNumber>;
231
- database: z.ZodString;
232
- user: z.ZodOptional<z.ZodString>;
233
- password: z.ZodOptional<z.ZodString>;
234
- ssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodEnum<{
235
- require: "require";
236
- prefer: "prefer";
237
- allow: "allow";
238
- disable: "disable";
239
- }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
240
- pool: z.ZodOptional<z.ZodObject<{
241
- min: z.ZodDefault<z.ZodNumber>;
242
- max: z.ZodDefault<z.ZodNumber>;
243
- idleTimeout: z.ZodDefault<z.ZodNumber>;
244
- acquireTimeout: z.ZodDefault<z.ZodNumber>;
245
- }, z.core.$strip>>;
246
- type: z.ZodLiteral<"postgresql">;
247
- }, z.core.$strip>, z.ZodObject<{
248
- url: z.ZodOptional<z.ZodString>;
249
- host: z.ZodDefault<z.ZodString>;
250
- port: z.ZodOptional<z.ZodNumber>;
251
- database: z.ZodString;
252
- user: z.ZodOptional<z.ZodString>;
253
- password: z.ZodOptional<z.ZodString>;
254
- ssl: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodEnum<{
255
- require: "require";
256
- prefer: "prefer";
257
- allow: "allow";
258
- disable: "disable";
259
- }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
260
- pool: z.ZodOptional<z.ZodObject<{
261
- min: z.ZodDefault<z.ZodNumber>;
262
- max: z.ZodDefault<z.ZodNumber>;
263
- idleTimeout: z.ZodDefault<z.ZodNumber>;
264
- acquireTimeout: z.ZodDefault<z.ZodNumber>;
265
- }, z.core.$strip>>;
266
- type: z.ZodLiteral<"mysql">;
267
- mysql: z.ZodOptional<z.ZodObject<{
268
- charset: z.ZodDefault<z.ZodString>;
269
- timezone: z.ZodOptional<z.ZodString>;
270
- }, z.core.$strip>>;
271
- }, z.core.$strip>], "type">;
272
- /** 数据库配置类型(判别联合体) */
273
- type ReldbConfig = z.infer<typeof ReldbConfigSchema>;
274
- /** SQLite 配置类型 */
275
- type SqliteConfig = z.infer<typeof SqliteConfigSchema>;
276
- /** PostgreSQL 配置类型 */
277
- type PostgresqlConfig = z.infer<typeof PostgresqlConfigSchema>;
278
- /** MySQL 配置类型 */
279
- type MysqlConfig = z.infer<typeof MysqlConfigSchema>;
280
- /**
281
- * 数据库配置输入类型(用于 init 等入口)
282
- *
283
- * 说明:Zod 的 default 会让输入端字段可省略,但输出端字段为必填。
284
- * 因此对外 API(如 reldb.init)更适合接收 ReldbConfigInput。
285
- */
286
- type ReldbConfigInput = z.input<typeof ReldbConfigSchema>;
5
+ import 'zod';
287
6
 
288
7
  /**
289
8
  * @h-ai/reldb — JSON 操作 SQL 构建器
290
9
  *
291
10
  * 为不同数据库后端提供统一的 JSON 路径操作 SQL 表达式构建能力。
292
- * 路径格式遵循 SQL/JSON Path 标准(`$.key` / `$.key.subkey` / `$[0]`)。
11
+ * 路径支持简单点号与方括号路径(`$.key` / `$.key.subkey` / `$[0]`),不是完整 SQL/JSON Path 校验器。
293
12
  *
294
13
  * 各数据库后端映射:
295
14
  *
@@ -299,7 +18,7 @@ type ReldbConfigInput = z.input<typeof ReldbConfigSchema>;
299
18
  * | set | json_set + json() | jsonb_set + ::jsonb | JSON_SET + CAST AS JSON |
300
19
  * | insert | json_insert + json() | jsonb_insert + ::jsonb | JSON_INSERT + CAST AS JSON |
301
20
  * | remove | json_remove | #- (text[]) | JSON_REMOVE |
302
- * | merge | json_patch | \|\| ::jsonb | JSON_MERGE_PATCH + CAST |
21
+ * | merge | json_patch | 参数化递归 CTE | JSON_MERGE_PATCH + CAST |
303
22
  *
304
23
  * @module reldb-json
305
24
  */
@@ -308,15 +27,12 @@ type ReldbConfigInput = z.input<typeof ReldbConfigSchema>;
308
27
  *
309
28
  * 包含可嵌入 SQL 语句的表达式片段与对应参数列表。
310
29
  * 参数占位符统一使用 `?`,各 Provider 会在执行前自动转换。
311
- *
312
30
  * @example
313
31
  * ```ts
314
- * const { sql, params } = reldb.json.set('settings', '$.theme', 'dark')
315
- * // 将 sql 和 params 嵌入到完整 SQL 中执行
316
- * await reldb.sql.execute(
317
- * `UPDATE users SET settings = ${sql} WHERE id = ?`,
318
- * [...params, userId],
319
- * )
32
+ * import { createJsonOps, type JsonSqlExpr } from '@h-ai/reldb'
33
+ *
34
+ * const expression: JsonSqlExpr = createJsonOps('postgresql').set('settings', '$.theme', 'dark')
35
+ * void [expression.sql, expression.params]
320
36
  * ```
321
37
  */
322
38
  interface JsonSqlExpr {
@@ -331,25 +47,16 @@ interface JsonSqlExpr {
331
47
  * 提供跨数据库统一的 JSON 路径操作 SQL 构建能力。
332
48
  * 所有方法返回 `JsonSqlExpr`,可嵌入 `reldb.sql.query` / `reldb.sql.execute` 等调用。
333
49
  *
334
- * 路径格式:遵循 SQL/JSON Path 标准,以 `$` 开头:
50
+ * 路径使用以下简单形式,建议以 `$` 开头:
335
51
  * - 对象字段:`$.key`、`$.key.subkey`
336
52
  * - 数组元素:`$[0]`、`$.items[1]`
337
- *
338
53
  * @example
339
54
  * ```ts
340
- * // 提取 JSON 字段值(用于 SELECT 或 WHERE)
341
- * const { sql, params } = reldb.json.extract('settings', '$.theme')
342
- * const rows = await reldb.sql.query(
343
- * `SELECT * FROM users WHERE ${sql} = ?`,
344
- * [...params, '"dark"'],
345
- * )
346
- *
347
- * // 设置 JSON 字段的某个路径(用于 UPDATE SET)
348
- * const { sql, params } = reldb.json.set('settings', '$.theme', 'dark')
349
- * await reldb.sql.execute(
350
- * `UPDATE users SET settings = ${sql} WHERE id = ?`,
351
- * [...params, userId],
352
- * )
55
+ * import { createJsonOps, type ReldbJsonOps } from '@h-ai/reldb'
56
+ *
57
+ * const json: ReldbJsonOps = createJsonOps('postgresql')
58
+ * const patch = json.merge('settings', { theme: 'dark', obsolete: null })
59
+ * void patch // 作为同一次 UPDATE 的 SQL 表达式执行,值在 params。
353
60
  * ```
354
61
  */
355
62
  interface ReldbJsonOps {
@@ -362,55 +69,52 @@ interface ReldbJsonOps {
362
69
  * @param column - 列名(或 SQL 列表达式,开发者负责安全性,禁止传入用户输入)
363
70
  * @param path - JSON 路径(如 `$.status`、`$.user.name`、`$[0]`)
364
71
  * @returns SQL 表达式与参数
365
- *
366
72
  * @example
367
73
  * ```ts
368
- * const { sql, params } = reldb.json.extract('data', '$.status')
369
- * // SQLite: sql = "json_extract(data, ?)", params = ["$.status"]
370
- * // PostgreSQL: sql = "data #> ?::text[]", params = [["status"]]
371
- * // MySQL: sql = "JSON_EXTRACT(data, ?)", params = ["$.status"]
74
+ * import { reldb } from '@h-ai/reldb'
75
+ *
76
+ * const expression = reldb.json.extract('settings', '$.theme')
77
+ * void [expression.sql, expression.params]
372
78
  * ```
373
79
  */
374
80
  extract: (column: string, path: string) => JsonSqlExpr;
375
81
  /**
376
82
  * JSON 路径设置表达式(创建或替换)
377
83
  *
378
- * 在 JSON 列的指定路径设置新值。若路径不存在则创建,若已存在则替换。
84
+ * 设置指定路径的值;PostgreSQL 要求父路径存在,其他后端按原生 JSON 函数处理缺失父路径。
379
85
  * 返回修改后的完整 JSON 值,通常用于 `UPDATE SET col = ...`。
380
86
  *
381
87
  * @param column - 列名(开发者负责安全性,禁止传入用户输入)
382
88
  * @param path - JSON 路径
383
89
  * @param value - 要设置的值(支持任意 JSON 兼容类型)
384
90
  * @returns SQL 表达式与参数
385
- *
386
91
  * @example
387
92
  * ```ts
388
- * const { sql, params } = reldb.json.set('settings', '$.theme', 'dark')
389
- * await reldb.sql.execute(
390
- * `UPDATE users SET settings = ${sql} WHERE id = ?`,
391
- * [...params, id],
392
- * )
93
+ * import { reldb } from '@h-ai/reldb'
94
+ *
95
+ * const expression = reldb.json.set('settings', '$.theme', 'dark')
96
+ * const result = await reldb.sql.execute(`UPDATE users SET settings = ${expression.sql} WHERE id = ?`, [...expression.params, 'u1'])
97
+ * if (!result.success) throw new Error(result.error.message)
393
98
  * ```
394
99
  */
395
100
  set: (column: string, path: string, value: unknown) => JsonSqlExpr;
396
101
  /**
397
102
  * JSON 路径插入表达式(仅当路径不存在时)
398
103
  *
399
- * 仅在指定路径不存在时插入新值,已存在的路径不会被覆盖。
104
+ * 使用后端原生插入语义:SQLite/MySQL 不覆盖已有值;PostgreSQL 对已有对象键报错,数组路径按 jsonb_insert 插入。
400
105
  * 返回修改后的完整 JSON 值。
401
106
  *
402
107
  * @param column - 列名(开发者负责安全性,禁止传入用户输入)
403
108
  * @param path - JSON 路径
404
109
  * @param value - 要插入的值
405
110
  * @returns SQL 表达式与参数
406
- *
407
111
  * @example
408
112
  * ```ts
409
- * const { sql, params } = reldb.json.insert('data', '$.newField', 'value')
410
- * await reldb.sql.execute(
411
- * `UPDATE items SET data = ${sql} WHERE id = ?`,
412
- * [...params, id],
413
- * )
113
+ * import { reldb } from '@h-ai/reldb'
114
+ *
115
+ * const expression = reldb.json.insert('settings', '$.newField', 'value')
116
+ * const result = await reldb.sql.execute(`UPDATE users SET settings = ${expression.sql} WHERE id = ?`, [...expression.params, 'u1'])
117
+ * if (!result.success) throw new Error(result.error.message)
414
118
  * ```
415
119
  */
416
120
  insert: (column: string, path: string, value: unknown) => JsonSqlExpr;
@@ -423,14 +127,13 @@ interface ReldbJsonOps {
423
127
  * @param column - 列名(开发者负责安全性,禁止传入用户输入)
424
128
  * @param path - JSON 路径
425
129
  * @returns SQL 表达式与参数
426
- *
427
130
  * @example
428
131
  * ```ts
429
- * const { sql, params } = reldb.json.remove('settings', '$.deprecated')
430
- * await reldb.sql.execute(
431
- * `UPDATE users SET settings = ${sql} WHERE id = ?`,
432
- * [...params, id],
433
- * )
132
+ * import { reldb } from '@h-ai/reldb'
133
+ *
134
+ * const expression = reldb.json.remove('settings', '$.obsolete')
135
+ * const result = await reldb.sql.execute(`UPDATE users SET settings = ${expression.sql} WHERE id = ?`, [...expression.params, 'u1'])
136
+ * if (!result.success) throw new Error(result.error.message)
434
137
  * ```
435
138
  */
436
139
  remove: (column: string, path: string) => JsonSqlExpr;
@@ -447,14 +150,13 @@ interface ReldbJsonOps {
447
150
  * @param column - 列名(开发者负责安全性,禁止传入用户输入)
448
151
  * @param patch - 要合并的 JSON 对象
449
152
  * @returns SQL 表达式与参数
450
- *
451
153
  * @example
452
154
  * ```ts
453
- * const { sql, params } = reldb.json.merge('profile', { bio: 'new bio', avatar: null })
454
- * await reldb.sql.execute(
455
- * `UPDATE users SET profile = ${sql} WHERE id = ?`,
456
- * [...params, id],
457
- * )
155
+ * import { reldb } from '@h-ai/reldb'
156
+ *
157
+ * const expression = reldb.json.merge('settings', { theme: 'dark', obsolete: null })
158
+ * const result = await reldb.sql.execute(`UPDATE users SET settings = ${expression.sql} WHERE id = ?`, [...expression.params, 'u1'])
159
+ * if (!result.success) throw new Error(result.error.message)
458
160
  * ```
459
161
  */
460
162
  merge: (column: string, patch: Record<string, unknown>) => JsonSqlExpr;
@@ -466,12 +168,11 @@ interface ReldbJsonOps {
466
168
  *
467
169
  * @param path - JSON 路径(以 `$` 开头)
468
170
  * @returns 路径段数组
469
- *
470
171
  * @example
471
172
  * ```ts
472
- * parseJsonPath('$.user.name') // ['user', 'name']
473
- * parseJsonPath('$.items[0]') // ['items', '0']
474
- * parseJsonPath('$[1]') // ['1']
173
+ * import { parseJsonPath } from '@h-ai/reldb'
174
+ *
175
+ * void parseJsonPath('$.items[0].name') // ['items', '0', 'name']
475
176
  * ```
476
177
  */
477
178
  declare function parseJsonPath(path: string): string[];
@@ -480,19 +181,28 @@ declare function parseJsonPath(path: string): string[];
480
181
  *
481
182
  * @param dbType - 数据库类型(来自 `reldb.config?.type`)
482
183
  * @returns JSON 操作实例
483
- *
484
184
  * @example
485
185
  * ```ts
486
- * // 通过 reldb.json 直接使用(推荐)
487
- * const { sql, params } = reldb.json.extract('data', '$.key')
186
+ * import { createJsonOps } from '@h-ai/reldb'
488
187
  *
489
- * // 手动创建(用于测试或特殊场景)
490
- * const jsonOps = createJsonOps('sqlite')
491
- * const { sql, params } = jsonOps.set('data', '$.key', 'value')
188
+ * const sqlite = createJsonOps('sqlite')
189
+ * const expression = sqlite.extract('settings', '$.theme')
190
+ * void expression
492
191
  * ```
493
192
  */
494
193
  declare function createJsonOps(dbType: 'sqlite' | 'postgresql' | 'mysql'): ReldbJsonOps;
495
194
 
195
+ /**
196
+ * HaiReldbError 的数据约束与操作契约。
197
+ * @example
198
+ * ```ts
199
+ * import { HaiReldbError } from '@h-ai/reldb'
200
+ * import { err } from '@h-ai/core'
201
+ *
202
+ * const result = err(HaiReldbError.QUERY_FAILED, 'Query failed')
203
+ * if (!result.success) void result.error.code
204
+ * ```
205
+ */
496
206
  declare const HaiReldbError: {
497
207
  CONNECTION_FAILED: _h_ai_core.HaiErrorDef;
498
208
  QUERY_FAILED: _h_ai_core.HaiErrorDef;
@@ -503,11 +213,11 @@ declare const HaiReldbError: {
503
213
  DUPLICATE_ENTRY: _h_ai_core.HaiErrorDef;
504
214
  DEADLOCK: _h_ai_core.HaiErrorDef;
505
215
  TIMEOUT: _h_ai_core.HaiErrorDef;
506
- POOL_EXHAUSTED: _h_ai_core.HaiErrorDef;
507
216
  NOT_INITIALIZED: _h_ai_core.HaiErrorDef;
508
- DDL_FAILED: _h_ai_core.HaiErrorDef;
217
+ POOL_EXHAUSTED: _h_ai_core.HaiErrorDef;
509
218
  UNSUPPORTED_TYPE: _h_ai_core.HaiErrorDef;
510
219
  CONFIG_ERROR: _h_ai_core.HaiErrorDef;
220
+ DDL_FAILED: _h_ai_core.HaiErrorDef;
511
221
  };
512
222
  /**
513
223
  * 列数据类型
@@ -517,7 +227,8 @@ declare const HaiReldbError: {
517
227
  * | 类型 | SQLite | PostgreSQL | MySQL |
518
228
  * |------------|---------|------------------|--------------|
519
229
  * | TEXT | TEXT | TEXT | VARCHAR(255) |
520
- * | INTEGER | INTEGER | INTEGER/SERIAL | INT/BIGINT |
230
+ * | INTEGER | INTEGER | INTEGER/BIGSERIAL | INT/BIGINT |
231
+ * | BIGINT | INTEGER | BIGINT | BIGINT |
521
232
  * | REAL | REAL | DOUBLE PRECISION | DOUBLE |
522
233
  * | BLOB | BLOB | BYTEA | BLOB |
523
234
  * | BOOLEAN | INTEGER | BOOLEAN | TINYINT(1) |
@@ -525,33 +236,28 @@ declare const HaiReldbError: {
525
236
  * | JSON | TEXT | JSONB | JSON |
526
237
  *
527
238
  * 注:MySQL 将 TEXT 映射为 VARCHAR(255) 以支持索引和 UNIQUE 约束。
528
- * INTEGER 在 MySQL autoIncrement 时映射为 BIGINT,否则映射为 INT。
239
+ * INTEGER 在 MySQL autoIncrement 时映射为 BIGINT,在 PostgreSQL 映射为 BIGSERIAL,否则为 32 位 INT/INTEGER。
240
+ * Unix 毫秒应声明为 BIGINT;原始 SQL/CRUD 的 BIGINT 返回形态取决于驱动,可能为 number/string/bigint。
241
+ * 使用 number 的业务仓库须校验 Number.isSafeInteger,超出范围不能直接强转而丢失精度。
242
+ * @example
243
+ * ```ts
244
+ * import type { ColumnType } from '@h-ai/reldb'
245
+ *
246
+ * const value: ColumnType = 'TEXT'
247
+ * void value
248
+ * ```
529
249
  */
530
- type ColumnType = 'TEXT' | 'INTEGER' | 'REAL' | 'BLOB' | 'BOOLEAN' | 'TIMESTAMP' | 'JSON';
250
+ type ColumnType = 'TEXT' | 'INTEGER' | 'BIGINT' | 'REAL' | 'BLOB' | 'BOOLEAN' | 'TIMESTAMP' | 'JSON';
531
251
  /**
532
252
  * 列定义接口
533
253
  *
534
254
  * 用于定义表的列结构。
535
- *
536
255
  * @example
537
256
  * ```ts
538
- * // 主键列
539
- * const idColumn: ReldbColumnDef = {
540
- * type: 'INTEGER',
541
- * primaryKey: true,
542
- * autoIncrement: true
543
- * }
257
+ * import type { ReldbColumnDef } from '@h-ai/reldb'
544
258
  *
545
- * // 带外键的列
546
- * const userIdColumn: ReldbColumnDef = {
547
- * type: 'INTEGER',
548
- * notNull: true,
549
- * references: {
550
- * table: 'users',
551
- * column: 'id',
552
- * onDelete: 'CASCADE'
553
- * }
554
- * }
259
+ * const value: ReldbColumnDef = { type: 'INTEGER', primaryKey: true, autoIncrement: true }
260
+ * void value
555
261
  * ```
556
262
  */
557
263
  interface ReldbColumnDef {
@@ -581,15 +287,12 @@ interface ReldbColumnDef {
581
287
  }
582
288
  /**
583
289
  * 表定义(列名到列定义的映射)
584
- *
585
290
  * @example
586
291
  * ```ts
587
- * const userTable: ReldbTableDef = {
588
- * id: { type: 'INTEGER', primaryKey: true, autoIncrement: true },
589
- * name: { type: 'TEXT', notNull: true },
590
- * email: { type: 'TEXT', unique: true },
591
- * created_at: { type: 'TIMESTAMP', defaultValue: 'NOW()' }
592
- * }
292
+ * import type { ReldbTableDef } from '@h-ai/reldb'
293
+ *
294
+ * const value: ReldbTableDef = { id: { type: 'TEXT', primaryKey: true }, name: { type: 'TEXT', notNull: true } }
295
+ * void value
593
296
  * ```
594
297
  */
595
298
  interface ReldbTableDef {
@@ -597,23 +300,12 @@ interface ReldbTableDef {
597
300
  }
598
301
  /**
599
302
  * 索引定义
600
- *
601
303
  * @example
602
304
  * ```ts
603
- * // 普通索引
604
- * const emailIndex: ReldbIndexDef = { columns: ['email'] }
305
+ * import type { ReldbIndexDef } from '@h-ai/reldb'
605
306
  *
606
- * // 唯一复合索引
607
- * const compositeIndex: ReldbIndexDef = {
608
- * columns: ['user_id', 'created_at'],
609
- * unique: true
610
- * }
611
- *
612
- * // 部分索引(带条件)
613
- * const partialIndex: ReldbIndexDef = {
614
- * columns: ['status'],
615
- * where: "status = 'active'"
616
- * }
307
+ * const value: ReldbIndexDef = { columns: ['email'], unique: true }
308
+ * void value
617
309
  * ```
618
310
  */
619
311
  interface ReldbIndexDef {
@@ -626,6 +318,13 @@ interface ReldbIndexDef {
626
318
  *
627
319
  * **⚠️ 安全警告:** `where` 为原始 SQL 片段,不会经过参数化处理,
628
320
  * **禁止**将用户输入直接拼接。仅用于开发者编写的静态条件。
321
+ * @example
322
+ * ```ts
323
+ * import type { CrudQueryOptions } from '@h-ai/reldb'
324
+ *
325
+ * const options: CrudQueryOptions = { where: 'name = ?', params: ['Alice'] }
326
+ * void options // 值走绑定参数;SQL 结构由开发者静态编写。
327
+ * ```
629
328
  */
630
329
  where?: string;
631
330
  }
@@ -633,18 +332,15 @@ interface ReldbIndexDef {
633
332
  * DDL(数据定义语言)操作接口
634
333
  *
635
334
  * 提供表结构管理功能,包括创建/删除表、添加/删除列、创建索引等。
636
- * 所有操作返回 `HaiResult<void>` 类型。
637
- *
335
+ * 结构修改返回 `HaiResult<void>`;hasTable 返回 `HaiResult<boolean>`,以实际签名为准。
638
336
  * @example
639
337
  * ```ts
640
- * // 创建表
641
- * const result = await reldb.ddl.createTable('users', {
642
- * id: { type: 'INTEGER', primaryKey: true, autoIncrement: true },
643
- * name: { type: 'TEXT', notNull: true }
644
- * })
645
- *
646
- * if (!result.success) {
647
- * // 处理错误:创建表失败(可根据 result.error.code / message 做兜底)
338
+ * import type { DdlOperations } from '@h-ai/reldb'
339
+ *
340
+ * async function use(operations: DdlOperations) {
341
+ * const result = await operations.createTable('users', { id: { type: 'TEXT', primaryKey: true } })
342
+ * if (!result.success) throw new Error(result.error.message)
343
+ * void result.data
648
344
  * }
649
345
  * ```
650
346
  */
@@ -656,13 +352,11 @@ interface DdlOperations {
656
352
  * @param ifNotExists - 是否使用 IF NOT EXISTS(默认 true)
657
353
  * @example
658
354
  * ```ts
659
- * const result = await reldb.ddl.createTable('users', {
660
- * id: { type: 'INTEGER', primaryKey: true, autoIncrement: true },
661
- * name: { type: 'TEXT', notNull: true }
662
- * })
663
- * if (!result.success) {
664
- * // 创建失败:根据 result.error.code / message 处理
665
- * }
355
+ * import { reldb } from '@h-ai/reldb'
356
+ *
357
+ * const result = await reldb.ddl.createTable('users', { id: { type: 'TEXT', primaryKey: true }, name: { type: 'TEXT' } })
358
+ * if (!result.success) throw new Error(result.error.message)
359
+ * void result.data
666
360
  * ```
667
361
  */
668
362
  createTable: (tableName: string, columns: ReldbTableDef, ifNotExists?: boolean) => Promise<HaiResult<void>>;
@@ -672,8 +366,11 @@ interface DdlOperations {
672
366
  * @param ifExists - 是否使用 IF EXISTS(默认 true)
673
367
  * @example
674
368
  * ```ts
675
- * await reldb.ddl.dropTable('users')
676
- * await reldb.ddl.dropTable('users_backup', false)
369
+ * import { reldb } from '@h-ai/reldb'
370
+ *
371
+ * const result = await reldb.ddl.dropTable('users_backup')
372
+ * if (!result.success) throw new Error(result.error.message)
373
+ * void result.data
677
374
  * ```
678
375
  */
679
376
  dropTable: (tableName: string, ifExists?: boolean) => Promise<HaiResult<void>>;
@@ -684,8 +381,11 @@ interface DdlOperations {
684
381
  * @param columnDef - 列定义
685
382
  * @example
686
383
  * ```ts
687
- * await reldb.ddl.addColumn('users', 'age', { type: 'INTEGER' })
688
- * await reldb.ddl.addColumn('users', 'email', { type: 'TEXT', unique: true })
384
+ * import { reldb } from '@h-ai/reldb'
385
+ *
386
+ * const result = await reldb.ddl.addColumn('users', 'age', { type: 'INTEGER' })
387
+ * if (!result.success) throw new Error(result.error.message)
388
+ * void result.data
689
389
  * ```
690
390
  */
691
391
  addColumn: (tableName: string, columnName: string, columnDef: ReldbColumnDef) => Promise<HaiResult<void>>;
@@ -695,7 +395,11 @@ interface DdlOperations {
695
395
  * @param columnName - 列名
696
396
  * @example
697
397
  * ```ts
698
- * await reldb.ddl.dropColumn('users', 'legacy_field')
398
+ * import { reldb } from '@h-ai/reldb'
399
+ *
400
+ * const result = await reldb.ddl.dropColumn('users', 'legacy_field')
401
+ * if (!result.success) throw new Error(result.error.message)
402
+ * void result.data
699
403
  * ```
700
404
  */
701
405
  dropColumn: (tableName: string, columnName: string) => Promise<HaiResult<void>>;
@@ -705,7 +409,11 @@ interface DdlOperations {
705
409
  * @param newName - 新表名
706
410
  * @example
707
411
  * ```ts
708
- * await reldb.ddl.renameTable('users_temp', 'users')
412
+ * import { reldb } from '@h-ai/reldb'
413
+ *
414
+ * const result = await reldb.ddl.renameTable('users_old', 'users')
415
+ * if (!result.success) throw new Error(result.error.message)
416
+ * void result.data
709
417
  * ```
710
418
  */
711
419
  renameTable: (oldName: string, newName: string) => Promise<HaiResult<void>>;
@@ -716,10 +424,11 @@ interface DdlOperations {
716
424
  * @param indexDef - 索引定义
717
425
  * @example
718
426
  * ```ts
719
- * await reldb.ddl.createIndex('users', 'idx_users_email', {
720
- * columns: ['email'],
721
- * unique: true,
722
- * })
427
+ * import { reldb } from '@h-ai/reldb'
428
+ *
429
+ * const result = await reldb.ddl.createIndex('users', 'users_name_idx', { columns: ['name'] })
430
+ * if (!result.success) throw new Error(result.error.message)
431
+ * void result.data
723
432
  * ```
724
433
  */
725
434
  createIndex: (tableName: string, indexName: string, indexDef: ReldbIndexDef) => Promise<HaiResult<void>>;
@@ -729,7 +438,11 @@ interface DdlOperations {
729
438
  * @param ifExists - 是否使用 IF EXISTS(默认 true)
730
439
  * @example
731
440
  * ```ts
732
- * await reldb.ddl.dropIndex('idx_users_email')
441
+ * import { reldb } from '@h-ai/reldb'
442
+ *
443
+ * const result = await reldb.ddl.dropIndex('users_name_idx')
444
+ * if (!result.success) throw new Error(result.error.message)
445
+ * void result.data
733
446
  * ```
734
447
  */
735
448
  dropIndex: (indexName: string, ifExists?: boolean) => Promise<HaiResult<void>>;
@@ -743,11 +456,11 @@ interface DdlOperations {
743
456
  * @param sql - DDL SQL 语句(必须为开发者静态构造,禁止包含用户输入)
744
457
  * @example
745
458
  * ```ts
746
- * // ✅ 安全:静态 SQL
747
- * await reldb.ddl.raw('ALTER TABLE users ADD COLUMN status TEXT')
459
+ * import { reldb } from '@h-ai/reldb'
748
460
  *
749
- * // ❌ 危险:拼接用户输入
750
- * await reldb.ddl.raw(`ALTER TABLE ${userInput} ADD COLUMN status TEXT`)
461
+ * const result = await reldb.ddl.raw('ALTER TABLE users ADD COLUMN status TEXT')
462
+ * if (!result.success) throw new Error(result.error.message)
463
+ * void result.data
751
464
  * ```
752
465
  */
753
466
  raw: (sql: string) => Promise<HaiResult<void>>;
@@ -756,12 +469,26 @@ interface DdlOperations {
756
469
  * 查询结果行类型
757
470
  *
758
471
  * 约定为键值对象,字段名与 SQL 返回列一致。
472
+ * @example
473
+ * ```ts
474
+ * import type { QueryRow } from '@h-ai/reldb'
475
+ *
476
+ * const value: QueryRow = { id: 'u1', name: 'Alice' }
477
+ * void value
478
+ * ```
759
479
  */
760
480
  type QueryRow = Record<string, unknown>;
761
481
  /**
762
482
  * 执行结果
763
483
  *
764
484
  * INSERT/UPDATE/DELETE 操作返回的结果。
485
+ * @example
486
+ * ```ts
487
+ * import type { ExecuteResult } from '@h-ai/reldb'
488
+ *
489
+ * const value: ExecuteResult = { changes: 1 }
490
+ * void value
491
+ * ```
765
492
  */
766
493
  interface ExecuteResult {
767
494
  /** 影响的行数 */
@@ -771,6 +498,13 @@ interface ExecuteResult {
771
498
  }
772
499
  /**
773
500
  * 规范化后的分页参数
501
+ * @example
502
+ * ```ts
503
+ * import type { NormalizedPagination } from '@h-ai/reldb'
504
+ *
505
+ * const value: NormalizedPagination = { page: 2, pageSize: 10, offset: 10, limit: 10 }
506
+ * void value
507
+ * ```
774
508
  */
775
509
  interface NormalizedPagination extends PaginationOptions {
776
510
  /** SQL offset */
@@ -780,6 +514,13 @@ interface NormalizedPagination extends PaginationOptions {
780
514
  }
781
515
  /**
782
516
  * 分页参数覆盖
517
+ * @example
518
+ * ```ts
519
+ * import type { PaginationOverrides } from '@h-ai/reldb'
520
+ *
521
+ * const value: PaginationOverrides = { defaultPageSize: 20, maxPageSize: 100 }
522
+ * void value
523
+ * ```
783
524
  */
784
525
  interface PaginationOverrides {
785
526
  /** 默认页码 */
@@ -791,6 +532,13 @@ interface PaginationOverrides {
791
532
  }
792
533
  /**
793
534
  * 分页查询参数
535
+ * @example
536
+ * ```ts
537
+ * import type { PaginationQueryOptions } from '@h-ai/reldb'
538
+ *
539
+ * const value: PaginationQueryOptions = { sql: 'SELECT id, name FROM users WHERE active = ?', params: [true], pagination: { page: 2, pageSize: 10 } }
540
+ * void value
541
+ * ```
794
542
  */
795
543
  interface PaginationQueryOptions {
796
544
  /** 数据查询 SQL(不含 LIMIT/OFFSET) */
@@ -804,37 +552,104 @@ interface PaginationQueryOptions {
804
552
  }
805
553
  /**
806
554
  * 数据读写操作接口(SQL / 事务共享)
555
+ * @example
556
+ * ```ts
557
+ * import type { DmlOperations } from '@h-ai/reldb'
558
+ *
559
+ * async function use(operations: DmlOperations) {
560
+ * const result = await operations.query<{ id: string }>('SELECT id FROM users WHERE name = ?', ['Alice'])
561
+ * if (!result.success) throw new Error(result.error.message)
562
+ * return result.data
563
+ * }
564
+ * ```
807
565
  */
808
566
  interface DmlOperations {
809
- /** 查询多行 */
567
+ /**
568
+ * 查询多行
569
+ * @example
570
+ * ```ts
571
+ * import { reldb } from '@h-ai/reldb'
572
+ *
573
+ * const result = await reldb.sql.query<{ id: string }>('SELECT id FROM users WHERE name = ?', ['Alice'])
574
+ * if (!result.success) throw new Error(result.error.message)
575
+ * void result.data
576
+ * ```
577
+ */
810
578
  query: <T = QueryRow>(sql: string, params?: unknown[]) => Promise<HaiResult<T[]>>;
811
- /** 查询单行 */
579
+ /**
580
+ * 查询单行
581
+ * @example
582
+ * ```ts
583
+ * import { reldb } from '@h-ai/reldb'
584
+ *
585
+ * const result = await reldb.sql.get<{ id: string }>('SELECT id FROM users WHERE name = ?', ['Alice'])
586
+ * if (!result.success) throw new Error(result.error.message)
587
+ * void result.data
588
+ * ```
589
+ */
812
590
  get: <T = QueryRow>(sql: string, params?: unknown[]) => Promise<HaiResult<T | null>>;
813
- /** 执行修改语句(INSERT/UPDATE/DELETE) */
591
+ /**
592
+ * 执行修改语句(INSERT/UPDATE/DELETE)
593
+ * @example
594
+ * ```ts
595
+ * import { reldb } from '@h-ai/reldb'
596
+ *
597
+ * const result = await reldb.sql.execute('UPDATE users SET name = ? WHERE id = ?', ['Alice', 'u1'])
598
+ * if (!result.success) throw new Error(result.error.message)
599
+ * void result.data
600
+ * ```
601
+ */
814
602
  execute: (sql: string, params?: unknown[]) => Promise<HaiResult<ExecuteResult>>;
815
- /** 批量执行多条语句(在同一事务上下文中) */
603
+ /**
604
+ * 批量执行多条语句(在同一事务上下文中)
605
+ * @example
606
+ * ```ts
607
+ * import { reldb } from '@h-ai/reldb'
608
+ *
609
+ * const result = await reldb.sql.batch([{ sql: 'UPDATE users SET name = ? WHERE id = ?', params: ['Alice', 'u1'] }])
610
+ * if (!result.success) throw new Error(result.error.message)
611
+ * void result.data
612
+ * ```
613
+ */
816
614
  batch: (statements: Array<{
817
615
  sql: string;
818
616
  params?: unknown[];
819
617
  }>) => Promise<HaiResult<void>>;
820
- /** 分页查询 */
618
+ /**
619
+ * 分页查询
620
+ * @example
621
+ * ```ts
622
+ * import { reldb } from '@h-ai/reldb'
623
+ *
624
+ * const result = await reldb.sql.queryPage<{ id: string }>({ sql: 'SELECT id FROM users', pagination: { page: 1, pageSize: 10 } })
625
+ * if (!result.success) throw new Error(result.error.message)
626
+ * void result.data
627
+ * ```
628
+ */
821
629
  queryPage: <T = QueryRow>(options: PaginationQueryOptions) => Promise<HaiResult<PaginatedResult<T>>>;
822
630
  }
823
- /** CRUD 查询条件 */
631
+ /**
632
+ * CRUD 查询条件
633
+ * @example
634
+ * ```ts
635
+ * import type { CrudQueryOptions } from '@h-ai/reldb'
636
+ *
637
+ * const value: CrudQueryOptions = { where: 'name = ?', params: ['Alice'], orderBy: 'id ASC', limit: 10 }
638
+ * void value
639
+ * ```
640
+ */
824
641
  interface CrudQueryOptions {
825
642
  /**
826
643
  * WHERE 子句(不包含 WHERE 关键字)
827
644
  *
828
645
  * **⚠️ 安全警告:** `where` 为原始 SQL 片段,**禁止**将用户输入直接拼接。
829
646
  * 动态值必须通过 `params` 占位符(`?`)传入。
830
- *
831
647
  * @example
832
648
  * ```ts
833
- * // ✅ 安全:占位符 + params
834
- * crud.findAll({ where: 'status = ? AND age > ?', params: ['active', 18] })
649
+ * import type { CrudQueryOptions } from '@h-ai/reldb'
835
650
  *
836
- * // ❌ 危险:拼接用户输入
837
- * crud.findAll({ where: `name = '${userInput}'` })
651
+ * const options: CrudQueryOptions = { where: 'name = ?', params: ['Alice'] }
652
+ * void options // 值走绑定参数;SQL 结构由开发者静态编写。
838
653
  * ```
839
654
  */
840
655
  where?: string;
@@ -847,13 +662,29 @@ interface CrudQueryOptions {
847
662
  /** OFFSET */
848
663
  offset?: number;
849
664
  }
850
- /** CRUD 分页查询条件 */
665
+ /**
666
+ * CRUD 分页查询条件
667
+ * @example
668
+ * ```ts
669
+ * import type { CrudPageOptions } from '@h-ai/reldb'
670
+ *
671
+ * const value: CrudPageOptions = { where: 'active = ?', params: [true], pagination: { page: 1, pageSize: 20 } }
672
+ * void value
673
+ * ```
674
+ */
851
675
  interface CrudPageOptions {
852
676
  /**
853
677
  * WHERE 子句(不包含 WHERE 关键字)
854
678
  *
855
679
  * **⚠️ 安全警告:** `where` 为原始 SQL 片段,**禁止**将用户输入直接拼接。
856
680
  * 动态值必须通过 `params` 占位符(`?`)传入。
681
+ * @example
682
+ * ```ts
683
+ * import type { CrudQueryOptions } from '@h-ai/reldb'
684
+ *
685
+ * const options: CrudQueryOptions = { where: 'name = ?', params: ['Alice'] }
686
+ * void options // 值走绑定参数;SQL 结构由开发者静态编写。
687
+ * ```
857
688
  */
858
689
  where?: string;
859
690
  /** 参数列表 */
@@ -865,19 +696,44 @@ interface CrudPageOptions {
865
696
  /** 分页参数覆盖 */
866
697
  overrides?: PaginationOverrides;
867
698
  }
868
- /** CRUD 统计条件 */
699
+ /**
700
+ * CRUD 统计条件
701
+ * @example
702
+ * ```ts
703
+ * import type { ReldbCrudCountOptions } from '@h-ai/reldb'
704
+ *
705
+ * const value: ReldbCrudCountOptions = { where: 'active = ?', params: [true] }
706
+ * void value
707
+ * ```
708
+ */
869
709
  interface ReldbCrudCountOptions {
870
710
  /**
871
711
  * WHERE 子句(不包含 WHERE 关键字)
872
712
  *
873
713
  * **⚠️ 安全警告:** `where` 为原始 SQL 片段,**禁止**将用户输入直接拼接。
874
714
  * 动态值必须通过 `params` 占位符(`?`)传入。
715
+ * @example
716
+ * ```ts
717
+ * import type { CrudQueryOptions } from '@h-ai/reldb'
718
+ *
719
+ * const options: CrudQueryOptions = { where: 'name = ?', params: ['Alice'] }
720
+ * void options // 值走绑定参数;SQL 结构由开发者静态编写。
721
+ * ```
875
722
  */
876
723
  where?: string;
877
724
  /** 参数列表 */
878
725
  params?: unknown[];
879
726
  }
880
- /** CRUD 配置 */
727
+ /**
728
+ * CRUD 配置
729
+ * @example
730
+ * ```ts
731
+ * import type { CrudConfig } from '@h-ai/reldb'
732
+ *
733
+ * const config: CrudConfig<{ id: string }> = { table: 'users', dbType: 'postgresql', select: ['id'], createColumns: ['id'], updateColumns: [] }
734
+ * void config
735
+ * ```
736
+ */
881
737
  interface CrudConfig<TItem> {
882
738
  /** 表名 */
883
739
  table: string;
@@ -894,7 +750,16 @@ interface CrudConfig<TItem> {
894
750
  /** 数据库类型 */
895
751
  dbType: DbType;
896
752
  }
897
- /** CRUD 字段定义 */
753
+ /**
754
+ * CRUD 字段定义
755
+ * @example
756
+ * ```ts
757
+ * import type { ReldbCrudFieldDefinition } from '@h-ai/reldb'
758
+ *
759
+ * const value: ReldbCrudFieldDefinition = { fieldName: 'name', columnName: 'name', def: { type: 'TEXT', notNull: true }, select: true, create: true, update: true }
760
+ * void value
761
+ * ```
762
+ */
898
763
  interface ReldbCrudFieldDefinition {
899
764
  /** 对象字段名 */
900
765
  fieldName: string;
@@ -909,7 +774,20 @@ interface ReldbCrudFieldDefinition {
909
774
  /** 是否允许更新 */
910
775
  update: boolean;
911
776
  }
912
- /** BaseReldbCrudRepository 配置 */
777
+ /**
778
+ * BaseReldbCrudRepository 配置
779
+ * @example
780
+ * ```ts
781
+ * import type { BaseReldbCrudRepositoryConfig } from '@h-ai/reldb'
782
+ *
783
+ * const config: BaseReldbCrudRepositoryConfig<{ id: string }> = {
784
+ * table: 'users', idField: 'id', fields: [
785
+ * { fieldName: 'id', columnName: 'id', def: { type: 'TEXT', primaryKey: true }, select: true, create: true, update: false },
786
+ * ],
787
+ * }
788
+ * void config
789
+ * ```
790
+ */
913
791
  interface BaseReldbCrudRepositoryConfig<TItem> {
914
792
  /** 表名 */
915
793
  table: string;
@@ -926,7 +804,19 @@ interface BaseReldbCrudRepositoryConfig<TItem> {
926
804
  /** 当前时间提供者(默认 Date.now) */
927
805
  nowProvider?: () => number;
928
806
  }
929
- /** CRUD 仓库接口 */
807
+ /**
808
+ * CRUD 仓库接口
809
+ * @example
810
+ * ```ts
811
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
812
+ *
813
+ * async function use(operations: ReldbCrudRepository<{ id: string }>) {
814
+ * const result = await operations.findById('u1')
815
+ * if (!result.success) throw new Error(result.error.message)
816
+ * return result.data
817
+ * }
818
+ * ```
819
+ */
930
820
  interface ReldbCrudRepository<TItem> {
931
821
  create: (data: Record<string, unknown>, tx?: DmlWithTxOperations) => Promise<HaiResult<ExecuteResult>>;
932
822
  createMany: (items: Array<Record<string, unknown>>, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>;
@@ -941,13 +831,37 @@ interface ReldbCrudRepository<TItem> {
941
831
  exists: (options?: ReldbCrudCountOptions, tx?: DmlWithTxOperations) => Promise<HaiResult<boolean>>;
942
832
  existsById: (id: unknown, tx?: DmlWithTxOperations) => Promise<HaiResult<boolean>>;
943
833
  }
944
- /** CRUD 管理器(统一入口) */
834
+ /**
835
+ * CRUD 管理器(统一入口)
836
+ * @example
837
+ * ```ts
838
+ * import type { CrudManager } from '@h-ai/reldb'
839
+ *
840
+ * async function use(operations: CrudManager) {
841
+ * const result = await operations.table<{ id: string }>({ table: 'users', dbType: 'postgresql' }).findById('u1')
842
+ * if (!result.success) throw new Error(result.error.message)
843
+ * return result.data
844
+ * }
845
+ * ```
846
+ */
945
847
  interface CrudManager {
946
848
  /** 获取单表 CRUD 仓库 */
947
849
  table: <TItem>(config: CrudConfig<TItem>) => ReldbCrudRepository<TItem>;
948
850
  }
949
851
  /**
950
852
  * 事务句柄接口(分步事务)
853
+ * @example
854
+ * ```ts
855
+ * import type { DmlWithTxOperations } from '@h-ai/reldb'
856
+ *
857
+ * async function use(operations: DmlWithTxOperations) {
858
+ * const result = await operations.execute('UPDATE users SET name = ? WHERE id = ?', ['Alice', 'u1'])
859
+ * if (!result.success) throw new Error(result.error.message)
860
+ * const committed = await operations.commit()
861
+ * if (!committed.success) throw new Error(committed.error.message)
862
+ * return result.data.changes
863
+ * }
864
+ * ```
951
865
  */
952
866
  interface DmlWithTxOperations extends DmlOperations {
953
867
  /** CRUD 管理器 */
@@ -961,18 +875,36 @@ interface DmlWithTxOperations extends DmlOperations {
961
875
  * 事务回调函数类型
962
876
  *
963
877
  * @param tx - 事务内操作对象
964
- * @returns 业务返回值(将被包装为 HaiResult)
878
+ * @returns 业务返回值(将被包装为 HaiResult);callback 抛错才回滚,返回失败 HaiResult 不会被自动展开。
965
879
  * @example
966
880
  * ```ts
967
- * const result = await reldb.tx.wrap(async (tx) => {
968
- * await tx.execute('INSERT INTO users (name) VALUES (?)', ['用户A'])
969
- * return await tx.get('SELECT * FROM users WHERE name = ?', ['用户A'])
970
- * })
881
+ * import type { TxWrapCallback } from '@h-ai/reldb'
882
+ *
883
+ * const insert: TxWrapCallback<number> = async (tx) => {
884
+ * const result = await tx.execute('INSERT INTO users (id, name) VALUES (?, ?)', ['u1', 'Alice'])
885
+ * if (!result.success) throw new Error(result.error.message) // 显式抛错触发 wrap 回滚。
886
+ * return result.data.changes
887
+ * }
888
+ * void insert
971
889
  * ```
972
890
  */
973
891
  type TxWrapCallback<T> = (tx: DmlWithTxOperations) => Promise<T>;
974
892
  /**
975
893
  * 事务管理器
894
+ * @example
895
+ * ```ts
896
+ * import type { TxManager } from '@h-ai/reldb'
897
+ *
898
+ * async function use(operations: TxManager) {
899
+ * const result = await operations.wrap(async (tx) => {
900
+ * const changed = await tx.execute('UPDATE users SET name = ? WHERE id = ?', ['Alice', 'u1'])
901
+ * if (!changed.success) throw new Error(changed.error.message)
902
+ * return changed.data.changes
903
+ * })
904
+ * if (!result.success) throw new Error(result.error.message)
905
+ * return result.data
906
+ * }
907
+ * ```
976
908
  */
977
909
  interface TxManager {
978
910
  /** 开启事务(分步事务) */
@@ -984,30 +916,21 @@ interface TxManager {
984
916
  * 数据库函数接口
985
917
  *
986
918
  * 统一的数据库访问入口,通过 `reldb` 对象提供所有数据库操作。
987
- *
988
919
  * @example
989
920
  * ```ts
990
921
  * import { reldb } from '@h-ai/reldb'
991
922
  *
992
- * // 初始化
993
- * await reldb.init({ type: 'sqlite', database: ':memory:' })
994
- *
995
- * // 检查状态
996
- * if (reldb.isInitialized) {
997
- * // 可读取当前数据库类型:reldb.config?.type
923
+ * const initialized = await reldb.init({ type: 'sqlite', database: ':memory:' }) // 仅示例/测试。
924
+ * if (!initialized.success) throw new Error(initialized.error.message)
925
+ * try {
926
+ * const created = await reldb.ddl.createTable('users', { id: { type: 'TEXT', primaryKey: true }, name: { type: 'TEXT' } })
927
+ * if (!created.success) throw new Error(created.error.message)
928
+ * const inserted = await reldb.sql.execute('INSERT INTO users (id, name) VALUES (?, ?)', ['u1', 'Alice'])
929
+ * if (!inserted.success) throw new Error(inserted.error.message)
930
+ * } finally {
931
+ * const closed = await reldb.close()
932
+ * if (!closed.success) throw new Error(closed.error.message)
998
933
  * }
999
- *
1000
- * // 使用 DDL
1001
- * await reldb.ddl.createTable('users', { ... })
1002
- *
1003
- * // 使用 SQL
1004
- * await reldb.sql.query('SELECT * FROM users')
1005
- *
1006
- * // 使用事务
1007
- * await reldb.tx.wrap(async (tx) => { ... })
1008
- *
1009
- * // 关闭连接
1010
- * await reldb.close()
1011
934
  * ```
1012
935
  */
1013
936
  interface ReldbFunctions {
@@ -1016,6 +939,14 @@ interface ReldbFunctions {
1016
939
  *
1017
940
  * @param config - 数据库配置
1018
941
  * @returns 初始化结果
942
+ * @example
943
+ * ```ts
944
+ * import { reldb } from '@h-ai/reldb'
945
+ *
946
+ * const result = await reldb.init({ type: 'sqlite', database: ':memory:' })
947
+ * if (!result.success) throw new Error(result.error.message)
948
+ * void result.data
949
+ * ```
1019
950
  */
1020
951
  init: (config: ReldbConfigInput) => Promise<HaiResult<void>>;
1021
952
  /** DDL 操作(表结构管理) */
@@ -1026,7 +957,7 @@ interface ReldbFunctions {
1026
957
  readonly crud: CrudManager;
1027
958
  /** 事务管理器 */
1028
959
  readonly tx: TxManager;
1029
- /** 当前数据库配置(未初始化时为 null) */
960
+ /** 当前数据库脱敏配置快照(未初始化时为 null) */
1030
961
  readonly config: ReldbConfig | null;
1031
962
  /** 是否已初始化 */
1032
963
  readonly isInitialized: boolean;
@@ -1044,49 +975,29 @@ interface ReldbFunctions {
1044
975
  * 返回的 SQL 片段可嵌入 `reldb.sql.query` / `reldb.sql.execute` 等调用。
1045
976
  *
1046
977
  * 未初始化时默认返回 SQLite 格式的构建器;初始化后自动匹配当前数据库类型。
1047
- *
1048
978
  * @example
1049
979
  * ```ts
1050
- * // 提取 JSON 字段值(用于 WHERE 条件)
1051
- * const { sql, params } = reldb.json.extract('settings', '$.theme')
1052
- * const rows = await reldb.sql.query(
1053
- * `SELECT * FROM users WHERE ${sql} = ?`,
1054
- * [...params, '"dark"'],
1055
- * )
1056
- *
1057
- * // 设置 JSON 字段路径
1058
- * const { sql, params } = reldb.json.set('settings', '$.theme', 'dark')
1059
- * await reldb.sql.execute(
1060
- * `UPDATE users SET settings = ${sql} WHERE id = ?`,
1061
- * [...params, userId],
1062
- * )
980
+ * import { reldb } from '@h-ai/reldb'
981
+ *
982
+ * const expression = reldb.json.set('settings', '$.theme', 'dark')
983
+ * const result = await reldb.sql.execute(`UPDATE users SET settings = ${expression.sql} WHERE id = ?`, [...expression.params, 'u1'])
984
+ * if (!result.success) throw new Error(result.error.message)
1063
985
  * ```
1064
986
  */
1065
987
  readonly json: ReldbJsonOps;
1066
- /** 关闭数据库连接 */
1067
- close: () => Promise<HaiResult<void>>;
1068
- }
1069
- /**
1070
- * 数据库 Provider 接口
1071
- *
1072
- * 内部使用,定义各数据库驱动需要实现的接口。
1073
- * 每个数据库类型(SQLite、PostgreSQL、MySQL)都有对应的 Provider 实现。
1074
- */
1075
- interface ReldbProvider {
1076
- /** DDL 操作(表结构管理) */
1077
- readonly ddl: DdlOperations;
1078
- /** SQL 操作(数据查询和修改) */
1079
- readonly sql: DmlOperations;
1080
- /** CRUD 管理器 */
1081
- readonly crud: CrudManager;
1082
- /** 事务管理器 */
1083
- readonly tx: TxManager;
1084
- /** 连接数据库 */
1085
- connect: (config: ReldbConfig) => Promise<HaiResult<void>>;
1086
- /** 关闭连接 */
988
+ /**
989
+ * 等待初始化/在途事务并关闭连接;清理失败后操作不可用,资源保留供重试。
990
+ * @returns 资源全部释放时成功;未初始化时同样成功。
991
+ * @example
992
+ * ```ts
993
+ * import { reldb } from '@h-ai/reldb'
994
+ *
995
+ * const result = await reldb.close()
996
+ * if (!result.success) throw new Error(result.error.message)
997
+ * void result.data
998
+ * ```
999
+ */
1087
1000
  close: () => Promise<HaiResult<void>>;
1088
- /** 是否已连接 */
1089
- isConnected: () => boolean;
1090
1001
  }
1091
1002
 
1092
1003
  /**
@@ -1107,21 +1018,24 @@ interface ReldbProvider {
1107
1018
  * - 自动填充主键、createdAt、updatedAt
1108
1019
  * - 跨数据库类型值转换(BOOLEAN / TIMESTAMP / JSON)
1109
1020
  * - 支持事务上下文(所有方法均接受可选 tx 参数)
1110
- *
1111
1021
  * @example
1112
1022
  * ```ts
1113
- * class UserRepository extends BaseReldbCrudRepository<User> {
1023
+ * import { BaseReldbCrudRepository, type ReldbFunctions } from '@h-ai/reldb'
1024
+ *
1025
+ * type User = { id: string, name: string }
1026
+ * class Users extends BaseReldbCrudRepository<User> {
1114
1027
  * constructor(db: ReldbFunctions) {
1115
- * super(db, {
1116
- * table: 'users',
1117
- * fields: [
1118
- * { fieldName: 'id', columnName: 'id', def: { type: 'INTEGER', primaryKey: true, autoIncrement: true }, select: true, create: false, update: false },
1119
- * { fieldName: 'name', columnName: 'name', def: { type: 'TEXT', notNull: true }, select: true, create: true, update: true },
1120
- * { fieldName: 'createdAt', columnName: 'created_at', def: { type: 'TIMESTAMP' }, select: true, create: true, update: false },
1121
- * ],
1122
- * })
1028
+ * super(db, { table: 'users', fields: [
1029
+ * { fieldName: 'id', columnName: 'id', def: { type: 'TEXT', primaryKey: true }, select: true, create: true, update: false },
1030
+ * { fieldName: 'name', columnName: 'name', def: { type: 'TEXT' }, select: true, create: true, update: true },
1031
+ * ] })
1123
1032
  * }
1124
1033
  * }
1034
+ * async function create(db: ReldbFunctions) { // db 已初始化。
1035
+ * const result = await new Users(db).create({ name: 'Alice' })
1036
+ * if (!result.success) throw new Error(result.error.message)
1037
+ * return result.data
1038
+ * }
1125
1039
  * ```
1126
1040
  */
1127
1041
  declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudRepository<TItem> {
@@ -1239,11 +1153,15 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1239
1153
  */
1240
1154
  private buildUpdatePayload;
1241
1155
  /**
1242
- * 等待初始化完成
1156
+ * 等待初始化完成(自动建表等)
1157
+ *
1158
+ * 内置 CRUD 方法均已在执行前调用;自定义方法若通过 `this.sql()` 直接执行原始
1159
+ * SQL(尤其是写操作或在事务中),应先 `await this.ensureReady()` 以避免表尚未
1160
+ * 建好时(例如刚 dropTable 后、或后端建表较慢时)产生「表不存在」的竞态失败。
1243
1161
  *
1244
1162
  * @returns 初始化结果
1245
1163
  */
1246
- private ensureReady;
1164
+ protected ensureReady(): Promise<HaiResult<void>>;
1247
1165
  /**
1248
1166
  * 创建单条记录
1249
1167
  *
@@ -1252,6 +1170,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1252
1170
  * @param data - 业务字段与值的映射
1253
1171
  * @param tx - 可选事务句柄
1254
1172
  * @returns 插入结果(含 changes、lastInsertRowid)
1173
+ * @example
1174
+ * ```ts
1175
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1176
+ *
1177
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1178
+ * const result = await repo.create({ name: 'Alice' })
1179
+ * if (!result.success) throw new Error(result.error.message)
1180
+ * return result.data
1181
+ * }
1182
+ * void use
1183
+ * ```
1255
1184
  */
1256
1185
  create(data: Record<string, unknown>, tx?: DmlWithTxOperations): Promise<HaiResult<ExecuteResult>>;
1257
1186
  /**
@@ -1262,6 +1191,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1262
1191
  * @param items - 待插入的业务数据数组
1263
1192
  * @param tx - 可选事务句柄
1264
1193
  * @returns 批量插入结果
1194
+ * @example
1195
+ * ```ts
1196
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1197
+ *
1198
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1199
+ * const result = await repo.createMany([{ name: 'Alice' }, { name: 'Bob' }])
1200
+ * if (!result.success) throw new Error(result.error.message)
1201
+ * return result.data
1202
+ * }
1203
+ * void use
1204
+ * ```
1265
1205
  */
1266
1206
  createMany(items: Array<Record<string, unknown>>, tx?: DmlWithTxOperations): Promise<HaiResult<void>>;
1267
1207
  /**
@@ -1289,6 +1229,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1289
1229
  * @param data - 业务字段与值的映射
1290
1230
  * @param tx - 可选事务句柄
1291
1231
  * @returns 执行结果(含 changes)
1232
+ * @example
1233
+ * ```ts
1234
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1235
+ *
1236
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1237
+ * const result = await repo.createOrUpdate({ id: 'u1', name: 'Alice' })
1238
+ * if (!result.success) throw new Error(result.error.message)
1239
+ * return result.data
1240
+ * }
1241
+ * void use
1242
+ * ```
1292
1243
  */
1293
1244
  createOrUpdate(data: Record<string, unknown>, tx?: DmlWithTxOperations): Promise<HaiResult<ExecuteResult>>;
1294
1245
  /**
@@ -1297,6 +1248,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1297
1248
  * @param id - 主键值
1298
1249
  * @param tx - 可选事务句柄
1299
1250
  * @returns 业务模型对象或 null(未找到)
1251
+ * @example
1252
+ * ```ts
1253
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1254
+ *
1255
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1256
+ * const result = await repo.findById('u1')
1257
+ * if (!result.success) throw new Error(result.error.message)
1258
+ * return result.data
1259
+ * }
1260
+ * void use
1261
+ * ```
1300
1262
  */
1301
1263
  findById(id: unknown, tx?: DmlWithTxOperations): Promise<HaiResult<TItem | null>>;
1302
1264
  /**
@@ -1307,6 +1269,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1307
1269
  * @param id - 主键值
1308
1270
  * @param tx - 可选事务句柄
1309
1271
  * @returns 业务模型对象(不存在时返回错误)
1272
+ * @example
1273
+ * ```ts
1274
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1275
+ *
1276
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1277
+ * const result = await repo.getById('u1')
1278
+ * if (!result.success) throw new Error(result.error.message)
1279
+ * return result.data
1280
+ * }
1281
+ * void use
1282
+ * ```
1310
1283
  */
1311
1284
  getById(id: unknown, tx?: DmlWithTxOperations): Promise<HaiResult<TItem>>;
1312
1285
  /**
@@ -1315,6 +1288,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1315
1288
  * @param options - 查询条件(where、orderBy、limit、offset)
1316
1289
  * @param tx - 可选事务句柄
1317
1290
  * @returns 业务模型数组
1291
+ * @example
1292
+ * ```ts
1293
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1294
+ *
1295
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1296
+ * const result = await repo.findAll({ where: 'name = ?', params: ['Alice'] })
1297
+ * if (!result.success) throw new Error(result.error.message)
1298
+ * return result.data
1299
+ * }
1300
+ * void use
1301
+ * ```
1318
1302
  */
1319
1303
  findAll(options?: CrudQueryOptions, tx?: DmlWithTxOperations): Promise<HaiResult<TItem[]>>;
1320
1304
  /**
@@ -1323,6 +1307,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1323
1307
  * @param options - 分页查询条件(where、orderBy、pagination、overrides)
1324
1308
  * @param tx - 可选事务句柄
1325
1309
  * @returns 分页结果(含 items、total、page、pageSize)
1310
+ * @example
1311
+ * ```ts
1312
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1313
+ *
1314
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1315
+ * const result = await repo.findPage({ pagination: { page: 1, pageSize: 10 }, orderBy: 'id ASC' })
1316
+ * if (!result.success) throw new Error(result.error.message)
1317
+ * return result.data
1318
+ * }
1319
+ * void use
1320
+ * ```
1326
1321
  */
1327
1322
  findPage(options: CrudPageOptions, tx?: DmlWithTxOperations): Promise<HaiResult<PaginatedResult<TItem>>>;
1328
1323
  /**
@@ -1334,6 +1329,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1334
1329
  * @param data - 待更新的业务字段
1335
1330
  * @param tx - 可选事务句柄
1336
1331
  * @returns 更新结果(含 changes)
1332
+ * @example
1333
+ * ```ts
1334
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1335
+ *
1336
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1337
+ * const result = await repo.updateById('u1', { name: 'Bob' })
1338
+ * if (!result.success) throw new Error(result.error.message)
1339
+ * return result.data
1340
+ * }
1341
+ * void use
1342
+ * ```
1337
1343
  */
1338
1344
  updateById(id: unknown, data: Record<string, unknown>, tx?: DmlWithTxOperations): Promise<HaiResult<ExecuteResult>>;
1339
1345
  /**
@@ -1342,6 +1348,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1342
1348
  * @param id - 主键值
1343
1349
  * @param tx - 可选事务句柄
1344
1350
  * @returns 删除结果(含 changes)
1351
+ * @example
1352
+ * ```ts
1353
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1354
+ *
1355
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1356
+ * const result = await repo.deleteById('u1')
1357
+ * if (!result.success) throw new Error(result.error.message)
1358
+ * return result.data
1359
+ * }
1360
+ * void use
1361
+ * ```
1345
1362
  */
1346
1363
  deleteById(id: unknown, tx?: DmlWithTxOperations): Promise<HaiResult<ExecuteResult>>;
1347
1364
  /**
@@ -1350,6 +1367,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1350
1367
  * @param options - 查询条件(where、params)
1351
1368
  * @param tx - 可选事务句柄
1352
1369
  * @returns 记录数
1370
+ * @example
1371
+ * ```ts
1372
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1373
+ *
1374
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1375
+ * const result = await repo.count({ where: 'name = ?', params: ['Alice'] })
1376
+ * if (!result.success) throw new Error(result.error.message)
1377
+ * return result.data
1378
+ * }
1379
+ * void use
1380
+ * ```
1353
1381
  */
1354
1382
  count(options?: ReldbCrudCountOptions, tx?: DmlWithTxOperations): Promise<HaiResult<number>>;
1355
1383
  /**
@@ -1358,6 +1386,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1358
1386
  * @param options - 查询条件(where、params)
1359
1387
  * @param tx - 可选事务句柄
1360
1388
  * @returns 是否存在
1389
+ * @example
1390
+ * ```ts
1391
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1392
+ *
1393
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1394
+ * const result = await repo.exists({ where: 'name = ?', params: ['Alice'] })
1395
+ * if (!result.success) throw new Error(result.error.message)
1396
+ * return result.data
1397
+ * }
1398
+ * void use
1399
+ * ```
1361
1400
  */
1362
1401
  exists(options?: ReldbCrudCountOptions, tx?: DmlWithTxOperations): Promise<HaiResult<boolean>>;
1363
1402
  /**
@@ -1366,6 +1405,17 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1366
1405
  * @param id - 主键值
1367
1406
  * @param tx - 可选事务句柄
1368
1407
  * @returns 是否存在
1408
+ * @example
1409
+ * ```ts
1410
+ * import type { ReldbCrudRepository } from '@h-ai/reldb'
1411
+ *
1412
+ * async function use(repo: ReldbCrudRepository<{ id: string, name: string }>) {
1413
+ * const result = await repo.existsById('u1')
1414
+ * if (!result.success) throw new Error(result.error.message)
1415
+ * return result.data
1416
+ * }
1417
+ * void use
1418
+ * ```
1369
1419
  */
1370
1420
  existsById(id: unknown, tx?: DmlWithTxOperations): Promise<HaiResult<boolean>>;
1371
1421
  }
@@ -1389,37 +1439,78 @@ declare abstract class BaseReldbCrudRepository<TItem> implements ReldbCrudReposi
1389
1439
  * - `reldb.json` - JSON 路径操作 SQL 构建器(提取、设置、插入、删除、合并)
1390
1440
  * - `reldb.config` - 当前配置
1391
1441
  * - `reldb.isInitialized` - 初始化状态
1392
- *
1393
1442
  * @example
1394
1443
  * ```ts
1395
1444
  * import { reldb } from '@h-ai/reldb'
1396
1445
  *
1397
- * // 初始化
1398
- * await reldb.init({ type: 'sqlite', database: ':memory:' })
1399
- *
1400
- * // DDL 操作
1401
- * await reldb.ddl.createTable('users', {
1402
- * id: { type: 'INTEGER', primaryKey: true, autoIncrement: true },
1403
- * name: { type: 'TEXT', notNull: true }
1404
- * })
1405
- *
1406
- * // SQL 操作
1407
- * await reldb.sql.execute('INSERT INTO users (name) VALUES (?)', ['张三'])
1408
- * const users = await reldb.sql.query('SELECT * FROM users')
1409
- *
1410
- * // 事务操作
1411
- * await reldb.tx.wrap(async (tx) => {
1412
- * await tx.execute('INSERT INTO users (name) VALUES (?)', ['用户1'])
1413
- * await tx.execute('INSERT INTO users (name) VALUES (?)', ['用户2'])
1414
- * return 'done'
1415
- * })
1416
- *
1417
- * // 关闭连接
1418
- * await reldb.close()
1446
+ * const initialized = await reldb.init({ type: 'sqlite', database: ':memory:' }) // 仅示例/测试。
1447
+ * if (!initialized.success) throw new Error(initialized.error.message)
1448
+ * try {
1449
+ * const created = await reldb.ddl.createTable('users', { id: { type: 'TEXT', primaryKey: true }, name: { type: 'TEXT' } })
1450
+ * if (!created.success) throw new Error(created.error.message)
1451
+ * const inserted = await reldb.sql.execute('INSERT INTO users (id, name) VALUES (?, ?)', ['u1', 'Alice'])
1452
+ * if (!inserted.success) throw new Error(inserted.error.message)
1453
+ * } finally {
1454
+ * const closed = await reldb.close()
1455
+ * if (!closed.success) throw new Error(closed.error.message)
1456
+ * }
1419
1457
  * ```
1420
1458
  */
1421
1459
  declare const reldb: ReldbFunctions;
1422
1460
 
1461
+ /** 模块维护自己的迁移;这里只提供跨数据库列检查、版本账本和执行边界。 */
1462
+
1463
+ /**
1464
+ * 一个可重入的模块升级步骤;只接收代码中固定的 SQL 与表名。
1465
+ * @example
1466
+ * ```ts
1467
+ * import type { SchemaMigration } from '@h-ai/reldb'
1468
+ * const steps: SchemaMigration[] = []
1469
+ * ```
1470
+ */
1471
+ interface SchemaMigration {
1472
+ version: number;
1473
+ name: string;
1474
+ needed: (sql: DmlOperations) => Promise<HaiResult<boolean>>;
1475
+ apply: (sql: DmlOperations) => Promise<HaiResult<unknown>>;
1476
+ }
1477
+ /**
1478
+ * 只读预检结果;生产升级需先停旧写入并备份数据库与共享缓存。
1479
+ * @example
1480
+ * ```ts
1481
+ * import type { SchemaMigrationPlan } from '@h-ai/reldb'
1482
+ * function changes(plan: SchemaMigrationPlan) { return plan.changes }
1483
+ * ```
1484
+ */
1485
+ interface SchemaMigrationPlan {
1486
+ module: string;
1487
+ currentVersion: number;
1488
+ targetVersion: number;
1489
+ changes: string[];
1490
+ requiresExclusiveAccess: boolean;
1491
+ }
1492
+ /**
1493
+ * 查询真实列名;不创建表,不把查询错误当成新安装。
1494
+ * @example
1495
+ * ```ts
1496
+ * import { reldb, schemaColumns } from '@h-ai/reldb'
1497
+ * const columns = await schemaColumns(reldb, 'hai_iam_users')
1498
+ * ```
1499
+ */
1500
+ declare function schemaColumns(db: ReldbFunctions, table: string, sql?: DmlOperations): Promise<HaiResult<string[]>>;
1501
+ /**
1502
+ * 预检或执行模块维护的版本迁移。SQLite/PostgreSQL 原子提交;MySQL DDL 隐式提交,步骤须可重入。
1503
+ * 失败不记录目标版本;重启重新检查真实结构。新版本账本拒绝旧代码向下迁移。
1504
+ * @example
1505
+ * ```ts
1506
+ * import { reldb, migrateSchema } from '@h-ai/reldb'
1507
+ * const plan = await migrateSchema(reldb, 'example', [], { dryRun: true })
1508
+ * ```
1509
+ */
1510
+ declare function migrateSchema(db: ReldbFunctions, module: string, steps: readonly SchemaMigration[], options?: {
1511
+ dryRun?: boolean;
1512
+ }): Promise<HaiResult<SchemaMigrationPlan>>;
1513
+
1423
1514
  /**
1424
1515
  * @h-ai/reldb — 安全工具
1425
1516
  *
@@ -1435,14 +1526,13 @@ declare const reldb: ReldbFunctions;
1435
1526
  *
1436
1527
  * @param name - 待校验的标识符
1437
1528
  * @returns 校验通过时返回 ok(name);不合法时返回错误 HaiResult
1438
- *
1439
1529
  * @example
1440
1530
  * ```ts
1441
- * const result = validateIdentifier('users')
1442
- * // result.success === true
1531
+ * import { validateIdentifier } from '@h-ai/reldb'
1443
1532
  *
1444
- * const bad = validateIdentifier('users; DROP TABLE')
1445
- * // bad.success === false
1533
+ * const checked = validateIdentifier('users')
1534
+ * if (!checked.success) throw new Error(checked.error.message)
1535
+ * void checked.data
1446
1536
  * ```
1447
1537
  */
1448
1538
  declare function validateIdentifier(name: string): HaiResult<string>;
@@ -1453,6 +1543,13 @@ declare function validateIdentifier(name: string): HaiResult<string>;
1453
1543
  *
1454
1544
  * @param names - 待校验的标识符数组
1455
1545
  * @returns 全部合法时返回 ok(undefined);否则返回第一个不合法项的错误
1546
+ * @example
1547
+ * ```ts
1548
+ * import { validateIdentifiers } from '@h-ai/reldb'
1549
+ *
1550
+ * const checked = validateIdentifiers(['users', 'id'])
1551
+ * if (!checked.success) throw new Error(checked.error.message)
1552
+ * ```
1456
1553
  */
1457
1554
  declare function validateIdentifiers(names: string[]): HaiResult<void>;
1458
1555
  /**
@@ -1464,11 +1561,13 @@ declare function validateIdentifiers(names: string[]): HaiResult<void>;
1464
1561
  *
1465
1562
  * @param name - 已校验的标识符
1466
1563
  * @returns 双引号包裹的安全标识符
1467
- *
1468
1564
  * @example
1469
1565
  * ```ts
1470
- * quoteIdentifier('users') // '"users"'
1471
- * quoteIdentifier('order') // '"order"' (安全引用 SQL 保留字)
1566
+ * import { quoteIdentifier, validateIdentifier } from '@h-ai/reldb'
1567
+ *
1568
+ * const checked = validateIdentifier('order')
1569
+ * if (!checked.success) throw new Error(checked.error.message)
1570
+ * void quoteIdentifier(checked.data)
1472
1571
  * ```
1473
1572
  */
1474
1573
  declare function quoteIdentifier(name: string): string;
@@ -1480,13 +1579,13 @@ declare function quoteIdentifier(name: string): string;
1480
1579
  *
1481
1580
  * @param value - 原始字符串
1482
1581
  * @returns 转义后的安全字符串
1483
- *
1484
1582
  * @example
1485
1583
  * ```ts
1486
- * escapeSqlString("it's") // "it''s"
1487
- * escapeSqlString("normal") // "normal"
1584
+ * import { escapeSqlString } from '@h-ai/reldb'
1585
+ *
1586
+ * void escapeSqlString("it's") // it''s;仅用于可信 DDL 字面量,业务值使用占位符。
1488
1587
  * ```
1489
1588
  */
1490
1589
  declare function escapeSqlString(value: string): string;
1491
1590
 
1492
- export { BaseReldbCrudRepository, type BaseReldbCrudRepositoryConfig, type ColumnType, type CrudConfig, type CrudManager, type CrudPageOptions, type CrudQueryOptions, type DbType, type DdlOperations, type DmlOperations, type DmlWithTxOperations, type ExecuteResult, HaiReldbError, type JsonSqlExpr, type MysqlConfig, MysqlConfigSchema, MysqlOptionsSchema, type NormalizedPagination, type PaginationOverrides, type PaginationQueryOptions, type PoolConfig, PoolConfigSchema, type PostgresqlConfig, PostgresqlConfigSchema, type QueryRow, type ReldbColumnDef, type ReldbConfig, type ReldbConfigInput, ReldbConfigSchema, type ReldbCrudCountOptions, type ReldbCrudFieldDefinition, type ReldbCrudRepository, type ReldbFunctions, type ReldbIndexDef, type ReldbJsonOps, type ReldbProvider, type ReldbTableDef, ReldbTypeSchema, type SqliteConfig, SqliteConfigSchema, SqliteOptionsSchema, type SslConfig, SslConfigSchema, type TxManager, type TxWrapCallback, createJsonOps, escapeSqlString, parseJsonPath, quoteIdentifier, reldb, validateIdentifier, validateIdentifiers };
1591
+ export { BaseReldbCrudRepository, type BaseReldbCrudRepositoryConfig, type ColumnType, type CrudConfig, type CrudManager, type CrudPageOptions, type CrudQueryOptions, DbType, type DdlOperations, type DmlOperations, type DmlWithTxOperations, type ExecuteResult, HaiReldbError, type JsonSqlExpr, type NormalizedPagination, type PaginationOverrides, type PaginationQueryOptions, type QueryRow, type ReldbColumnDef, ReldbConfig, ReldbConfigInput, type ReldbCrudCountOptions, type ReldbCrudFieldDefinition, type ReldbCrudRepository, type ReldbFunctions, type ReldbIndexDef, type ReldbJsonOps, type ReldbTableDef, type SchemaMigration, type SchemaMigrationPlan, type TxManager, type TxWrapCallback, createJsonOps, escapeSqlString, migrateSchema, parseJsonPath, quoteIdentifier, reldb, schemaColumns, validateIdentifier, validateIdentifiers };