monsqlize 1.2.1 → 1.2.2
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/CHANGELOG.md +2 -1
- package/README.md +106 -53
- package/index.d.ts +1 -0
- package/lib/index.js +54 -2
- package/lib/model/index.js +41 -1
- package/lib/mongodb/index.js +25 -0
- package/package.json +2 -2
- package/types/model/definition.ts +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 变更日志 (CHANGELOG)
|
|
2
2
|
|
|
3
3
|
> **说明**: 版本概览摘要,详细变更见 [changelogs/](./changelogs/) 目录
|
|
4
|
-
> **最后更新**: 2026-04-
|
|
4
|
+
> **最后更新**: 2026-04-24
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
| 版本 | 日期 | 变更摘要 | 详细 |
|
|
11
11
|
|------|------|---------|------|
|
|
12
|
+
| [v1.2.2](./changelogs/v1.2.2.md) | 2026-04-24 | 🆕 **新功能**:Model 数据源绑定 — `connection: { pool?, database? }` 支持 Model 绑定指定连接池和/或数据库,四种组合路由,向后兼容;🐛 **Bug Fix**:修复 `Model._clear()` 导致 `msq.model()` 实例缓存失效失效,populate 关系丢失问题 | [查看](./changelogs/v1.2.2.md) |
|
|
12
13
|
| [v1.2.1](./changelogs/v1.2.1.md) | 2026-04-13 | 🐛 **Bug 修复**:`msq.model()` 实例缓存 + 索引去重 + 死代码清理 + `types/monsqlize.ts` 补全 `model()` / `collection()` 类型 | [查看](./changelogs/v1.2.1.md) |
|
|
13
14
|
| [v1.2.0](./changelogs/v1.2.0.md) | 2026-04-13 | 🐛 **Bug 修复 + 新功能**:`findPage` 正式支持 `projection` 投影参数(修复静默忽略问题)+ 有效投影策略自动保护游标排序字段 + 8 个测试用例 | [查看](./changelogs/v1.2.0.md) |
|
|
14
15
|
| [v1.1.9](./changelogs/v1.1.9.md) | 2026-04-02 | 🚨 **P1 Bug 修复**:MultiLevelCache L2→L1 回填 TTL 缺失(null 永久驻留 L1)+ 新增 `backfillLocalTTL` 配置 + Redis `getWithTTL` 方法 + 14 个回归测试 | [查看](./changelogs/v1.1.9.md) |
|
package/README.md
CHANGED
|
@@ -314,78 +314,102 @@ await msq.close();
|
|
|
314
314
|
|
|
315
315
|
> **📦 依赖说明**: Model 层需要 `schema-dsl` 包支持(已随 monsqlize 自动安装,无需额外操作)
|
|
316
316
|
|
|
317
|
+
Model 层有两种使用方式,二者**互斥**,选其一即可:
|
|
318
|
+
|
|
319
|
+
| 方式 | 适合场景 |
|
|
320
|
+
|------|---------|
|
|
321
|
+
| **手动注册**(`Model.define()`)| 少量 Model、测试环境、需要精确控制加载顺序 |
|
|
322
|
+
| **自动加载**(`models:` 配置项)| 生产环境,Model 文件统一放在一个目录下 |
|
|
323
|
+
|
|
324
|
+
#### 方式一:手动注册
|
|
325
|
+
|
|
317
326
|
```javascript
|
|
318
327
|
const MonSQLize = require('monsqlize');
|
|
319
328
|
const { Model } = MonSQLize;
|
|
320
329
|
|
|
321
|
-
|
|
322
|
-
type: 'mongodb',
|
|
323
|
-
databaseName: 'mydb',
|
|
324
|
-
config: { uri: 'mongodb://localhost:27017' },
|
|
325
|
-
cache: { enabled: true },
|
|
326
|
-
models: './models' // 🆕 v1.0.7: 自动加载 Model 文件
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
await msq.connect(); // 自动加载 models/*.model.js
|
|
330
|
-
|
|
331
|
-
// 1. 定义 Model(带 Schema 验证、Relations 和 Hooks)
|
|
330
|
+
// 1. 先在 connect() 之前调用 Model.define() 注册所有 Model
|
|
332
331
|
Model.define('users', {
|
|
333
|
-
// 🔴 Schema 验证(默认启用,v1.0.7+,基于 schema-dsl 库)
|
|
334
332
|
schema: (dsl) => dsl({
|
|
335
|
-
username: 'string:3-32!',
|
|
336
|
-
email: 'email!',
|
|
337
|
-
password: 'string:6-!',
|
|
338
|
-
age: 'number:0-120'
|
|
339
|
-
role: 'string?' // 可选字符串
|
|
333
|
+
username: 'string:3-32!',
|
|
334
|
+
email: 'email!',
|
|
335
|
+
password: 'string:6-!',
|
|
336
|
+
age: 'number:0-120'
|
|
340
337
|
}),
|
|
341
|
-
|
|
342
|
-
// Relations(关联查询)
|
|
343
338
|
relations: {
|
|
344
|
-
posts: {
|
|
345
|
-
from: 'posts',
|
|
346
|
-
localField: '_id',
|
|
347
|
-
foreignField: 'userId',
|
|
348
|
-
single: false
|
|
349
|
-
}
|
|
339
|
+
posts: { from: 'posts', localField: '_id', foreignField: 'userId', single: false }
|
|
350
340
|
},
|
|
351
|
-
|
|
352
|
-
// Hooks(生命周期钩子)
|
|
353
341
|
hooks: (model) => ({
|
|
354
|
-
insert: {
|
|
355
|
-
before: async (ctx, doc) => {
|
|
356
|
-
doc.createdAt = new Date(); // 自动添加时间戳
|
|
357
|
-
return doc;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
342
|
+
insert: { before: async (ctx, doc) => { doc.createdAt = new Date(); return doc; } }
|
|
360
343
|
}),
|
|
361
|
-
|
|
362
|
-
// 自定义方法
|
|
363
344
|
methods: (model) => ({
|
|
364
|
-
instance: {
|
|
365
|
-
|
|
366
|
-
checkPassword(password) {
|
|
367
|
-
return this.password === password;
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
static: {
|
|
371
|
-
// Model 方法
|
|
372
|
-
async findByUsername(username) {
|
|
373
|
-
return await model.findOne({ username });
|
|
374
|
-
}
|
|
375
|
-
}
|
|
345
|
+
instance: { checkPassword(password) { return this.password === password; } },
|
|
346
|
+
static: { async findByUsername(username) { return await model.findOne({ username }); } }
|
|
376
347
|
})
|
|
377
348
|
});
|
|
378
349
|
|
|
379
350
|
Model.define('posts', {
|
|
380
|
-
schema: (dsl) => dsl({
|
|
381
|
-
title: 'string:1-200!',
|
|
382
|
-
content: 'string!',
|
|
383
|
-
userId: 'string!'
|
|
384
|
-
})
|
|
351
|
+
schema: (dsl) => dsl({ title: 'string:1-200!', content: 'string!', userId: 'string!' })
|
|
385
352
|
});
|
|
386
353
|
|
|
387
|
-
// 2.
|
|
354
|
+
// 2. 创建实例并连接
|
|
355
|
+
const msq = new MonSQLize({
|
|
356
|
+
type: 'mongodb',
|
|
357
|
+
databaseName: 'mydb',
|
|
358
|
+
config: { uri: 'mongodb://localhost:27017' },
|
|
359
|
+
cache: { enabled: true }
|
|
360
|
+
});
|
|
361
|
+
await msq.connect();
|
|
362
|
+
|
|
363
|
+
// 3. 获取 Model 并使用
|
|
388
364
|
const User = msq.model('users');
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
#### 方式二:自动加载(推荐用于生产环境)
|
|
368
|
+
|
|
369
|
+
将每个 Model 单独放在一个文件里,`connect()` 时自动扫描目录加载,无需手动 `Model.define()`:
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
// app.js
|
|
373
|
+
const path = require('path');
|
|
374
|
+
|
|
375
|
+
const msq = new MonSQLize({
|
|
376
|
+
type: 'mongodb',
|
|
377
|
+
databaseName: 'mydb',
|
|
378
|
+
config: { uri: 'mongodb://localhost:27017' },
|
|
379
|
+
// 推荐用绝对路径,避免受 process.cwd() 影响
|
|
380
|
+
models: path.join(__dirname, 'models')
|
|
381
|
+
// 或完整配置:
|
|
382
|
+
// models: { path: path.join(__dirname, 'models'), pattern: '*.model.js', recursive: true }
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
await msq.connect(); // ← 自动扫描 models/*.model.{js,ts,mjs,cjs}
|
|
386
|
+
|
|
387
|
+
const User = msq.model('users'); // 直接使用,无需 Model.define()
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
> 相对路径(如 `'./models'`)以 `process.cwd()` 为基准,即 Node.js 进程的启动目录。为避免歧义,推荐始终使用 `path.join(__dirname, 'models')` 这样的绝对路径。
|
|
391
|
+
|
|
392
|
+
```javascript
|
|
393
|
+
// models/user.model.js ← 每个 Model 独立一个文件
|
|
394
|
+
module.exports = {
|
|
395
|
+
name: 'users', // 集合名称(必需)
|
|
396
|
+
schema: (dsl) => dsl({
|
|
397
|
+
username: 'string:3-32!',
|
|
398
|
+
email: 'email!'
|
|
399
|
+
}),
|
|
400
|
+
methods: (model) => ({
|
|
401
|
+
static: {
|
|
402
|
+
async findByUsername(username) { return await model.findOne({ username }); }
|
|
403
|
+
}
|
|
404
|
+
})
|
|
405
|
+
};
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
> 详细说明(完整配置项、文件格式、错误处理)见 [docs/model.md — Model 自动加载](./docs/model.md#model-自动加载v107)
|
|
409
|
+
|
|
410
|
+
#### 两种方式共同的后续操作
|
|
411
|
+
|
|
412
|
+
```javascript
|
|
389
413
|
|
|
390
414
|
// ✅ Schema 验证自动生效
|
|
391
415
|
try {
|
|
@@ -432,6 +456,35 @@ await User.insertOne(doc, { skipValidation: true });
|
|
|
432
456
|
- ✅ **Relations** - 定义表关系(hasOne/hasMany/belongsTo)
|
|
433
457
|
- ✅ **自定义方法** - instance 方法注入到文档,static 方法挂载到 Model
|
|
434
458
|
- ✅ **自动缓存** - Populate 查询结果也会缓存
|
|
459
|
+
- ✅ **数据源绑定** - `connection: { pool?, database? }` 绑定指定连接池和/或数据库(v1.2.2+)
|
|
460
|
+
|
|
461
|
+
**数据源绑定示例(v1.2.2+)**:
|
|
462
|
+
|
|
463
|
+
```js
|
|
464
|
+
// 在多连接池场景中,将 Model 绑定到指定的连接池 + 数据库
|
|
465
|
+
const msq = new MonSQLize({
|
|
466
|
+
uri: 'mongodb://localhost:27017',
|
|
467
|
+
databaseName: 'main_db',
|
|
468
|
+
pools: [{ name: 'analytics', uri: 'mongodb://analytics-host:27017' }]
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
// 绑定到不同数据库(使用默认连接池)
|
|
472
|
+
Model.define('AuditLog', {
|
|
473
|
+
schema: (dsl) => dsl({ action: 'string!', userId: 'string!' }),
|
|
474
|
+
connection: { database: 'audit_db' }
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// 绑定到不同连接池 + 不同数据库
|
|
478
|
+
Model.define('AnalyticsReport', {
|
|
479
|
+
schema: (dsl) => dsl({ reportId: 'string!', data: 'object' }),
|
|
480
|
+
connection: { pool: 'analytics', database: 'reports_db' }
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// 调用时自动路由,无需手动切换
|
|
484
|
+
const AuditLogModel = msq.model('AuditLog'); // → audit_db(默认池)
|
|
485
|
+
const ReportModel = msq.model('AnalyticsReport'); // → reports_db(analytics 池)
|
|
486
|
+
const UserModel = msq.model('users'); // → main_db(原逻辑,向后兼容)
|
|
487
|
+
```
|
|
435
488
|
|
|
436
489
|
📖 **详细文档**:[Model 层完整指南](./docs/model.md) | [Populate API](./docs/populate.md) | [Hooks API](./docs/hooks.md) | [Schema 验证](./docs/model.md#schema-验证)
|
|
437
490
|
|
package/index.d.ts
CHANGED
|
@@ -178,6 +178,7 @@ declare module 'monsqlize' {
|
|
|
178
178
|
export import DefaultValue = Model.DefaultValue;
|
|
179
179
|
export import HookContext = Model.HookContext;
|
|
180
180
|
export import ValidationResult = Model.ValidationResult;
|
|
181
|
+
export import ModelConnection = Model.ModelConnection;
|
|
181
182
|
export import ModelDefinition = Model.ModelDefinition;
|
|
182
183
|
export import RelationConfig = Model.RelationConfig;
|
|
183
184
|
export import PopulateConfig = Model.PopulateConfig;
|
package/lib/index.js
CHANGED
|
@@ -737,8 +737,11 @@ module.exports = class {
|
|
|
737
737
|
// 获取 Model 定义
|
|
738
738
|
const modelDef = Model.get(collectionName);
|
|
739
739
|
|
|
740
|
-
// 获取 collection
|
|
741
|
-
const
|
|
740
|
+
// 获取 collection 实例(v1.2.2+ 支持 connection 路由)
|
|
741
|
+
const connection = modelDef.definition.connection;
|
|
742
|
+
const collection = (connection && (connection.pool || connection.database))
|
|
743
|
+
? this._resolveModelCollection(collectionName, connection)
|
|
744
|
+
: this.dbInstance.collection(collectionName);
|
|
742
745
|
|
|
743
746
|
// 创建 ModelInstance 并缓存
|
|
744
747
|
const instance = new Model.ModelInstance(collection, modelDef.definition, this);
|
|
@@ -749,6 +752,55 @@ module.exports = class {
|
|
|
749
752
|
return instance;
|
|
750
753
|
}
|
|
751
754
|
|
|
755
|
+
/**
|
|
756
|
+
* 解析 Model 绑定的 collection(内部方法)
|
|
757
|
+
*
|
|
758
|
+
* 根据 Model 定义中的 connection 配置,将请求路由到正确的连接池和数据库。
|
|
759
|
+
*
|
|
760
|
+
* 四种组合:
|
|
761
|
+
* 1. pool + database → 指定池、指定数据库
|
|
762
|
+
* 2. pool 只配置 → 指定池、实例默认 databaseName
|
|
763
|
+
* 3. database 只配置 → 默认连接池、指定数据库
|
|
764
|
+
* 4. 均未配置 → 原逻辑(此方法不会被调用)
|
|
765
|
+
*
|
|
766
|
+
* @private
|
|
767
|
+
* @param {string} collectionName - 集合名称
|
|
768
|
+
* @param {{ pool?: string, database?: string }} connection - Model 的 connection 配置
|
|
769
|
+
* @returns {Object} monSQLize 包装 collection 对象
|
|
770
|
+
* @since v1.2.2
|
|
771
|
+
*/
|
|
772
|
+
_resolveModelCollection(collectionName, connection) {
|
|
773
|
+
const poolName = connection.pool;
|
|
774
|
+
const dbName = connection.database || this.databaseName;
|
|
775
|
+
|
|
776
|
+
if (poolName) {
|
|
777
|
+
if (!this._poolManager) {
|
|
778
|
+
const err = new Error(
|
|
779
|
+
`Model '${collectionName}' requires pool '${poolName}' but no pools are configured. ` +
|
|
780
|
+
`Add 'pools' to MonSQLize constructor options.`
|
|
781
|
+
);
|
|
782
|
+
err.code = 'NO_POOL_MANAGER';
|
|
783
|
+
throw err;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
const client = this._poolManager._getPool(poolName);
|
|
787
|
+
if (!client) {
|
|
788
|
+
const availablePools = this._poolManager.getPoolNames().join(', ');
|
|
789
|
+
const err = new Error(
|
|
790
|
+
`Pool '${poolName}' not found. Available pools: [${availablePools}]`
|
|
791
|
+
);
|
|
792
|
+
err.code = 'POOL_NOT_FOUND';
|
|
793
|
+
throw err;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// 指定池 + 数据库:通过 adapter 的 collectionFromClient 复用包装逻辑
|
|
797
|
+
return this._adapter.collectionFromClient(client, dbName, collectionName);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// 只切换数据库,用默认连接
|
|
801
|
+
return this.dbInstance.db(dbName).collection(collectionName);
|
|
802
|
+
}
|
|
803
|
+
|
|
752
804
|
/**
|
|
753
805
|
* 获取集合实例(代理方法)
|
|
754
806
|
*
|
package/lib/model/index.js
CHANGED
|
@@ -160,6 +160,11 @@ class Model {
|
|
|
160
160
|
this._validateOptions(definition.options);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
// ========== 验证 connection 配置(v1.2.2+)==========
|
|
164
|
+
if (definition.connection) {
|
|
165
|
+
this._validateConnection(definition.connection);
|
|
166
|
+
}
|
|
167
|
+
|
|
163
168
|
// ========== 解析 timestamps 配置 ==========
|
|
164
169
|
const timestampsConfig = this._parseTimestampsConfig(
|
|
165
170
|
definition.options?.timestamps,
|
|
@@ -222,6 +227,37 @@ class Model {
|
|
|
222
227
|
}
|
|
223
228
|
}
|
|
224
229
|
|
|
230
|
+
/**
|
|
231
|
+
* 验证 connection 配置
|
|
232
|
+
*
|
|
233
|
+
* @private
|
|
234
|
+
* @param {Object} connection - connection 配置对象
|
|
235
|
+
* @throws {Error} 配置不合法时抛出错误
|
|
236
|
+
*
|
|
237
|
+
* @since v1.2.2
|
|
238
|
+
*/
|
|
239
|
+
static _validateConnection(connection) {
|
|
240
|
+
if (!connection || typeof connection !== 'object') {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (connection.pool !== undefined) {
|
|
245
|
+
if (typeof connection.pool !== 'string' || connection.pool.trim() === '') {
|
|
246
|
+
const err = new Error('connection.pool must be a non-empty string');
|
|
247
|
+
err.code = 'INVALID_MODEL_DEFINITION';
|
|
248
|
+
throw err;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (connection.database !== undefined) {
|
|
253
|
+
if (typeof connection.database !== 'string' || connection.database.trim() === '') {
|
|
254
|
+
const err = new Error('connection.database must be a non-empty string');
|
|
255
|
+
err.code = 'INVALID_MODEL_DEFINITION';
|
|
256
|
+
throw err;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
225
261
|
/**
|
|
226
262
|
* 验证 options 配置
|
|
227
263
|
* @private
|
|
@@ -454,8 +490,12 @@ class Model {
|
|
|
454
490
|
* @private
|
|
455
491
|
*/
|
|
456
492
|
static _clear() {
|
|
493
|
+
// 将所有已注册名标记为需要缓存失效,让 msq.model() 重建 ModelInstance
|
|
494
|
+
for (const name of this._registry.keys()) {
|
|
495
|
+
this._redefinedNames.add(name);
|
|
496
|
+
}
|
|
457
497
|
this._registry.clear();
|
|
458
|
-
|
|
498
|
+
// 注意:不清除 _redefinedNames,确保 msq 实例缓存能感知本次 clear
|
|
459
499
|
}
|
|
460
500
|
}
|
|
461
501
|
|
package/lib/mongodb/index.js
CHANGED
|
@@ -336,6 +336,31 @@ module.exports = class {
|
|
|
336
336
|
};
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
+
/**
|
|
340
|
+
* 从指定 MongoClient 创建包装 collection(用于多连接池 Model 绑定场景)
|
|
341
|
+
*
|
|
342
|
+
* 当 Model 定义了 `connection.pool` 时,`msq.model()` 会调用此方法,
|
|
343
|
+
* 将指定连接池的 MongoClient 传入,复用现有 collection() 的完整包装逻辑
|
|
344
|
+
* (runner、缓存、慢查询等),避免重复实现。
|
|
345
|
+
*
|
|
346
|
+
* 线程安全说明:Node.js 单线程,临时替换 this.client 的同步操作无竞态风险。
|
|
347
|
+
*
|
|
348
|
+
* @param {import('mongodb').MongoClient} client - 指定连接池的 MongoClient 实例
|
|
349
|
+
* @param {string} databaseName - 数据库名称
|
|
350
|
+
* @param {string} collectionName - 集合名称
|
|
351
|
+
* @returns {Object} monSQLize 包装 collection 对象
|
|
352
|
+
* @since v1.2.2
|
|
353
|
+
*/
|
|
354
|
+
collectionFromClient(client, databaseName, collectionName) {
|
|
355
|
+
const originalClient = this.client;
|
|
356
|
+
this.client = client;
|
|
357
|
+
try {
|
|
358
|
+
return this.collection(databaseName, collectionName);
|
|
359
|
+
} finally {
|
|
360
|
+
this.client = originalClient;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
339
364
|
/**
|
|
340
365
|
* 关闭连接并释放资源
|
|
341
366
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monsqlize",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "A lightweight MongoDB ORM with multi-level caching, transaction support, distributed features, Saga distributed transactions, unified expression system with 122 operators, and universal function caching (100% MongoDB support)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
},
|
|
115
115
|
"dependencies": {
|
|
116
116
|
"async-lock": "^1.4.1",
|
|
117
|
-
"mongodb": "^6.
|
|
117
|
+
"mongodb": "^6.21.0",
|
|
118
118
|
"schema-dsl": "^1.2.4",
|
|
119
119
|
"ssh2": "^1.17.0"
|
|
120
120
|
}
|
|
@@ -106,5 +106,47 @@ export interface ModelDefinition<T = any> {
|
|
|
106
106
|
* }
|
|
107
107
|
*/
|
|
108
108
|
statics?: Record<string, (...args: any[]) => any>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 数据源绑定配置(v1.2.2+)
|
|
112
|
+
*
|
|
113
|
+
* 声明此 Model 使用哪个连接池和/或数据库。
|
|
114
|
+
* 不配置时行为与 v1.2.1 完全相同(向后兼容)。
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* // 绑定到指定连接池 + 数据库
|
|
118
|
+
* connection: { pool: 'analytics', database: 'reports_db' }
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* // 只切换数据库(使用默认连接池)
|
|
122
|
+
* connection: { database: 'logs_db' }
|
|
123
|
+
*
|
|
124
|
+
* @since v1.2.2
|
|
125
|
+
*/
|
|
126
|
+
connection?: ModelConnection;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Model 数据源绑定配置
|
|
131
|
+
*
|
|
132
|
+
* 声明 Model 使用哪个连接池(pool)和/或数据库(database)。
|
|
133
|
+
* 两个字段均为可选:
|
|
134
|
+
* - 只指定 pool → 使用该池 + 实例初始化时的 databaseName
|
|
135
|
+
* - 只指定 database → 使用默认连接池 + 指定数据库
|
|
136
|
+
* - 两者都指定 → 使用指定池 + 指定数据库
|
|
137
|
+
* - 均不指定 → 与原来完全相同(向后兼容)
|
|
138
|
+
*
|
|
139
|
+
* @since v1.2.2
|
|
140
|
+
*/
|
|
141
|
+
export interface ModelConnection {
|
|
142
|
+
/**
|
|
143
|
+
* 连接池名称,须与 MonSQLize 构造函数 `pools[].name` 对应
|
|
144
|
+
*/
|
|
145
|
+
pool?: string;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* 数据库名称,不指定时使用实例初始化时的 `databaseName`
|
|
149
|
+
*/
|
|
150
|
+
database?: string;
|
|
109
151
|
}
|
|
110
152
|
|