monsqlize 1.0.2 → 1.0.5

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.
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Model 乐观锁版本控制功能
3
+ *
4
+ * 功能:
5
+ * 1. 插入时自动初始化 version: 0
6
+ * 2. 更新时自动递增版本号
7
+ * 3. 支持并发冲突检测
8
+ * 4. 支持自定义字段名
9
+ *
10
+ * 使用示例:
11
+ * ```javascript
12
+ * Model.define('users', {
13
+ * options: {
14
+ * version: true // 或 { enabled: true, field: '__v' }
15
+ * }
16
+ * });
17
+ *
18
+ * // 插入时自动初始化
19
+ * await User.insertOne({ username: 'john' });
20
+ * // { _id, username: 'john', version: 0 }
21
+ *
22
+ * // 更新时自动递增
23
+ * await User.updateOne({ _id, version: 0 }, { $set: { status: 'active' } });
24
+ * // 实际执行:{ $set: { status: 'active' }, $inc: { version: 1 } }
25
+ *
26
+ * // 并发冲突检测
27
+ * const result = await User.updateOne({ _id, version: 0 }, { $set: { status: 'inactive' } });
28
+ * // result.modifiedCount === 0(版本号不匹配,更新失败)
29
+ * ```
30
+ *
31
+ * @module lib/model/features/version
32
+ */
33
+
34
+ /**
35
+ * 解析版本控制配置
36
+ *
37
+ * @param {boolean|object} versionConfig - 版本控制配置
38
+ * @returns {object|null} 解析后的配置对象
39
+ */
40
+ function parseVersionConfig(versionConfig) {
41
+ if (!versionConfig) {
42
+ return null;
43
+ }
44
+
45
+ // 简单模式:version: true
46
+ if (versionConfig === true) {
47
+ return {
48
+ enabled: true,
49
+ field: 'version'
50
+ };
51
+ }
52
+
53
+ // 完整配置模式
54
+ if (typeof versionConfig === 'object') {
55
+ return {
56
+ enabled: versionConfig.enabled !== false,
57
+ field: versionConfig.field || 'version'
58
+ };
59
+ }
60
+
61
+ return null;
62
+ }
63
+
64
+ /**
65
+ * 为 Model 实例设置版本控制功能
66
+ *
67
+ * @param {object} modelInstance - Model 实例
68
+ * @param {boolean|object} versionConfig - 版本控制配置
69
+ */
70
+ function setupVersion(modelInstance, versionConfig) {
71
+ // 解析配置
72
+ const config = parseVersionConfig(versionConfig);
73
+
74
+ if (!config || !config.enabled) {
75
+ return; // 未启用,直接返回
76
+ }
77
+
78
+ const { field } = config;
79
+
80
+ // 保存配置到 Model 实例(供测试验证)
81
+ modelInstance._versionConfig = config;
82
+
83
+ // ========== 功能1: 插入时初始化版本号 ==========
84
+
85
+ // 保存原始方法
86
+ const originalInsertOne = modelInstance.collection.insertOne.bind(modelInstance.collection);
87
+ const originalInsertMany = modelInstance.collection.insertMany.bind(modelInstance.collection);
88
+
89
+ // 覆盖 insertOne
90
+ modelInstance.collection.insertOne = async function(doc, options) {
91
+ // 只在用户未手动设置时添加版本号
92
+ if (doc && typeof doc === 'object' && doc[field] === undefined) {
93
+ doc[field] = 0;
94
+ }
95
+ return await originalInsertOne(doc, options);
96
+ };
97
+
98
+ // 覆盖 insertMany
99
+ modelInstance.collection.insertMany = async function(docs, options) {
100
+ if (Array.isArray(docs)) {
101
+ docs.forEach(doc => {
102
+ if (doc && typeof doc === 'object' && doc[field] === undefined) {
103
+ doc[field] = 0;
104
+ }
105
+ });
106
+ }
107
+ return await originalInsertMany(docs, options);
108
+ };
109
+
110
+ // ========== 功能2: 更新时自动递增版本号 ==========
111
+
112
+ // 保存原始方法
113
+ const originalUpdateOne = modelInstance.collection.updateOne.bind(modelInstance.collection);
114
+ const originalUpdateMany = modelInstance.collection.updateMany.bind(modelInstance.collection);
115
+
116
+ // 覆盖 updateOne
117
+ modelInstance.collection.updateOne = async function(filter, update, options) {
118
+ // 检查 update 是否为空
119
+ if (update && typeof update === 'object') {
120
+ // 检查用户是否已手动设置 $inc.version
121
+ if (!update.$inc || update.$inc[field] === undefined) {
122
+ // 自动添加 $inc
123
+ if (!update.$inc) {
124
+ update.$inc = {};
125
+ }
126
+ update.$inc[field] = 1;
127
+ }
128
+ }
129
+ return await originalUpdateOne(filter, update, options);
130
+ };
131
+
132
+ // 覆盖 updateMany
133
+ modelInstance.collection.updateMany = async function(filter, update, options) {
134
+ // 检查 update 是否为空
135
+ if (update && typeof update === 'object') {
136
+ // 检查用户是否已手动设置 $inc.version
137
+ if (!update.$inc || update.$inc[field] === undefined) {
138
+ // 自动添加 $inc
139
+ if (!update.$inc) {
140
+ update.$inc = {};
141
+ }
142
+ update.$inc[field] = 1;
143
+ }
144
+ }
145
+ return await originalUpdateMany(filter, update, options);
146
+ };
147
+
148
+ // 注意:并发冲突检测通过 filter 中的版本号自然实现
149
+ // 用户提供 { _id, version: 0 } 时,如果版本号不匹配,matchedCount 为 0
150
+ }
151
+
152
+ module.exports = {
153
+ setupVersion,
154
+ parseVersionConfig // 导出供测试使用
155
+ };
156
+