@yanit/jsondb 0.1.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.
Files changed (118) hide show
  1. package/README.md +903 -0
  2. package/dist/bin/cli-export.d.ts +7 -0
  3. package/dist/bin/cli-export.d.ts.map +1 -0
  4. package/dist/bin/cli-export.js +318 -0
  5. package/dist/bin/cli-export.js.map +1 -0
  6. package/dist/bin/cli-import.d.ts +7 -0
  7. package/dist/bin/cli-import.d.ts.map +1 -0
  8. package/dist/bin/cli-import.js +298 -0
  9. package/dist/bin/cli-import.js.map +1 -0
  10. package/dist/bin/server.d.ts +7 -0
  11. package/dist/bin/server.d.ts.map +1 -0
  12. package/dist/bin/server.js +92 -0
  13. package/dist/bin/server.js.map +1 -0
  14. package/dist/examples/sql-example.d.ts +7 -0
  15. package/dist/examples/sql-example.d.ts.map +1 -0
  16. package/dist/examples/sql-example.js +131 -0
  17. package/dist/examples/sql-example.js.map +1 -0
  18. package/dist/src/BulkOp.d.ts +74 -0
  19. package/dist/src/BulkOp.d.ts.map +1 -0
  20. package/dist/src/BulkOp.js +143 -0
  21. package/dist/src/BulkOp.js.map +1 -0
  22. package/dist/src/Collection.d.ts +232 -0
  23. package/dist/src/Collection.d.ts.map +1 -0
  24. package/dist/src/Collection.js +705 -0
  25. package/dist/src/Collection.js.map +1 -0
  26. package/dist/src/Cursor.d.ts +94 -0
  27. package/dist/src/Cursor.d.ts.map +1 -0
  28. package/dist/src/Cursor.js +259 -0
  29. package/dist/src/Cursor.js.map +1 -0
  30. package/dist/src/Database.d.ts +98 -0
  31. package/dist/src/Database.d.ts.map +1 -0
  32. package/dist/src/Database.js +198 -0
  33. package/dist/src/Database.js.map +1 -0
  34. package/dist/src/Operators.d.ts +73 -0
  35. package/dist/src/Operators.d.ts.map +1 -0
  36. package/dist/src/Operators.js +339 -0
  37. package/dist/src/Operators.js.map +1 -0
  38. package/dist/src/QueryCache.d.ts +87 -0
  39. package/dist/src/QueryCache.d.ts.map +1 -0
  40. package/dist/src/QueryCache.js +155 -0
  41. package/dist/src/QueryCache.js.map +1 -0
  42. package/dist/src/SQLExecutor.d.ts +60 -0
  43. package/dist/src/SQLExecutor.d.ts.map +1 -0
  44. package/dist/src/SQLExecutor.js +317 -0
  45. package/dist/src/SQLExecutor.js.map +1 -0
  46. package/dist/src/SQLParser.d.ts +181 -0
  47. package/dist/src/SQLParser.d.ts.map +1 -0
  48. package/dist/src/SQLParser.js +640 -0
  49. package/dist/src/SQLParser.js.map +1 -0
  50. package/dist/src/Schema.d.ts +92 -0
  51. package/dist/src/Schema.d.ts.map +1 -0
  52. package/dist/src/Schema.js +253 -0
  53. package/dist/src/Schema.js.map +1 -0
  54. package/dist/src/Transaction.d.ts +118 -0
  55. package/dist/src/Transaction.d.ts.map +1 -0
  56. package/dist/src/Transaction.js +233 -0
  57. package/dist/src/Transaction.js.map +1 -0
  58. package/dist/src/Utils.d.ts +68 -0
  59. package/dist/src/Utils.d.ts.map +1 -0
  60. package/dist/src/Utils.js +187 -0
  61. package/dist/src/Utils.js.map +1 -0
  62. package/dist/src/errors.d.ts +58 -0
  63. package/dist/src/errors.d.ts.map +1 -0
  64. package/dist/src/errors.js +85 -0
  65. package/dist/src/errors.js.map +1 -0
  66. package/dist/src/index.d.ts +39 -0
  67. package/dist/src/index.d.ts.map +1 -0
  68. package/dist/src/index.js +44 -0
  69. package/dist/src/index.js.map +1 -0
  70. package/dist/test/basic.test.d.ts +5 -0
  71. package/dist/test/basic.test.d.ts.map +1 -0
  72. package/dist/test/basic.test.js +283 -0
  73. package/dist/test/basic.test.js.map +1 -0
  74. package/dist/test/index.test.d.ts +5 -0
  75. package/dist/test/index.test.d.ts.map +1 -0
  76. package/dist/test/index.test.js +126 -0
  77. package/dist/test/index.test.js.map +1 -0
  78. package/dist/test/jsonb.test.d.ts +5 -0
  79. package/dist/test/jsonb.test.d.ts.map +1 -0
  80. package/dist/test/jsonb.test.js +165 -0
  81. package/dist/test/jsonb.test.js.map +1 -0
  82. package/dist/test/optimization.test.d.ts +6 -0
  83. package/dist/test/optimization.test.d.ts.map +1 -0
  84. package/dist/test/optimization.test.js +196 -0
  85. package/dist/test/optimization.test.js.map +1 -0
  86. package/dist/test/schema.test.d.ts +5 -0
  87. package/dist/test/schema.test.d.ts.map +1 -0
  88. package/dist/test/schema.test.js +197 -0
  89. package/dist/test/schema.test.js.map +1 -0
  90. package/dist/test/sql.test.d.ts +7 -0
  91. package/dist/test/sql.test.d.ts.map +1 -0
  92. package/dist/test/sql.test.js +21 -0
  93. package/dist/test/sql.test.js.map +1 -0
  94. package/package.json +73 -0
  95. package/src/BulkOp.js +181 -0
  96. package/src/BulkOp.ts +191 -0
  97. package/src/Collection.js +843 -0
  98. package/src/Collection.ts +896 -0
  99. package/src/Cursor.js +315 -0
  100. package/src/Cursor.ts +319 -0
  101. package/src/Database.js +244 -0
  102. package/src/Database.ts +268 -0
  103. package/src/Operators.js +382 -0
  104. package/src/Operators.ts +375 -0
  105. package/src/QueryCache.js +190 -0
  106. package/src/QueryCache.ts +208 -0
  107. package/src/SQLExecutor.ts +391 -0
  108. package/src/SQLParser.ts +814 -0
  109. package/src/Schema.js +292 -0
  110. package/src/Schema.ts +317 -0
  111. package/src/Transaction.js +291 -0
  112. package/src/Transaction.ts +313 -0
  113. package/src/Utils.js +205 -0
  114. package/src/Utils.ts +205 -0
  115. package/src/errors.js +93 -0
  116. package/src/errors.ts +93 -0
  117. package/src/index.js +90 -0
  118. package/src/index.ts +106 -0
@@ -0,0 +1,198 @@
1
+ /**
2
+ * 数据库类 - 管理数据库和集合
3
+ * 支持 async/await 异步操作
4
+ */
5
+ import { readFile, writeFile, mkdir, readdir, rm } from 'fs/promises';
6
+ import { existsSync } from 'fs';
7
+ import { join } from 'path';
8
+ import { Collection } from './Collection.js';
9
+ import { ensureDir } from './Utils.js';
10
+ import { DatabaseNotFoundError, CollectionExistsError } from './errors.js';
11
+ /**
12
+ * Database 类
13
+ * 表示一个数据库,提供集合管理和数据库操作
14
+ */
15
+ export class Database {
16
+ dbPath;
17
+ _metaFile;
18
+ _meta;
19
+ _collections;
20
+ options;
21
+ /**
22
+ * @param dbPath - 数据库路径
23
+ * @param options - 数据库选项
24
+ */
25
+ constructor(dbPath, options = {}) {
26
+ this.dbPath = dbPath;
27
+ this._metaFile = join(dbPath, '_meta.json');
28
+ this._meta = null;
29
+ this._collections = new Map();
30
+ this.options = {
31
+ jsonb: options.jsonb || false,
32
+ cacheTTL: options.cacheTTL || 5000,
33
+ enableQueryCache: options.enableQueryCache !== false,
34
+ queryCacheTTL: options.queryCacheTTL || 30000
35
+ };
36
+ }
37
+ /**
38
+ * 打开数据库
39
+ */
40
+ async open() {
41
+ // 如果数据库不存在,创建它
42
+ if (!existsSync(this.dbPath)) {
43
+ await mkdir(this.dbPath, { recursive: true });
44
+ this._meta = {
45
+ name: this.dbNameFromPath,
46
+ version: '1.0.0',
47
+ createdAt: new Date().toISOString(),
48
+ collections: []
49
+ };
50
+ await this._saveMeta();
51
+ }
52
+ else {
53
+ // 加载元数据
54
+ await this._loadMeta();
55
+ }
56
+ return this;
57
+ }
58
+ /**
59
+ * 从路径获取数据库名
60
+ */
61
+ get dbNameFromPath() {
62
+ return this.dbPath.split(/[\\/]/).pop() || 'default';
63
+ }
64
+ /**
65
+ * 加载元数据
66
+ */
67
+ async _loadMeta() {
68
+ if (!existsSync(this._metaFile)) {
69
+ throw new DatabaseNotFoundError(this.dbPath);
70
+ }
71
+ const content = await readFile(this._metaFile, 'utf-8');
72
+ this._meta = JSON.parse(content);
73
+ }
74
+ /**
75
+ * 保存元数据
76
+ */
77
+ async _saveMeta() {
78
+ ensureDir(this._metaFile);
79
+ const content = JSON.stringify(this._meta, null, 2);
80
+ await writeFile(this._metaFile, content, 'utf-8');
81
+ }
82
+ /**
83
+ * 关闭数据库
84
+ */
85
+ async close() {
86
+ // 保存所有集合数据
87
+ for (const collection of this._collections.values()) {
88
+ // Collection 会自动保存
89
+ }
90
+ this._collections.clear();
91
+ this._meta = null;
92
+ }
93
+ /**
94
+ * 获取集合
95
+ */
96
+ collection(name) {
97
+ // 检查缓存
98
+ if (this._collections.has(name)) {
99
+ return this._collections.get(name);
100
+ }
101
+ // 创建新集合
102
+ const collection = new Collection(this, name);
103
+ this._collections.set(name, collection);
104
+ return collection;
105
+ }
106
+ /**
107
+ * 创建集合
108
+ */
109
+ async createCollection(name, options = {}) {
110
+ const collectionFile = join(this.dbPath, `${name}.json`);
111
+ // 检查集合是否已存在
112
+ if (existsSync(collectionFile)) {
113
+ throw new CollectionExistsError(name);
114
+ }
115
+ // 创建集合文件
116
+ const initialData = {
117
+ _meta: {
118
+ name,
119
+ count: 0,
120
+ indexes: options.indexes || []
121
+ },
122
+ _documents: [],
123
+ _indexes: {}
124
+ };
125
+ ensureDir(collectionFile);
126
+ await writeFile(collectionFile, JSON.stringify(initialData, null, 2), 'utf-8');
127
+ // 更新元数据
128
+ if (!this._meta.collections.includes(name)) {
129
+ this._meta.collections.push(name);
130
+ await this._saveMeta();
131
+ }
132
+ const collection = new Collection(this, name);
133
+ this._collections.set(name, collection);
134
+ return collection;
135
+ }
136
+ /**
137
+ * 删除集合
138
+ */
139
+ async dropCollection(name) {
140
+ const collectionFile = join(this.dbPath, `${name}.json`);
141
+ if (!existsSync(collectionFile)) {
142
+ return { acknowledged: false };
143
+ }
144
+ // 删除文件
145
+ await rm(collectionFile);
146
+ // 更新元数据
147
+ this._meta.collections = this._meta.collections.filter(c => c !== name);
148
+ await this._saveMeta();
149
+ // 清除缓存
150
+ this._collections.delete(name);
151
+ return { acknowledged: true };
152
+ }
153
+ /**
154
+ * 列出所有集合
155
+ */
156
+ async listCollections() {
157
+ // 从文件系统读取最新的集合列表
158
+ const files = await readdir(this.dbPath);
159
+ const collectionFiles = files
160
+ .filter(file => file.endsWith('.json') && file !== '_meta.json')
161
+ .map(file => file.replace('.json', ''));
162
+ return collectionFiles;
163
+ }
164
+ /**
165
+ * 获取数据库统计信息
166
+ */
167
+ async stats() {
168
+ const collections = await this.listCollections();
169
+ let totalDocuments = 0;
170
+ let totalSize = 0;
171
+ for (const name of collections) {
172
+ const collection = this.collection(name);
173
+ const stats = await collection.stats();
174
+ totalDocuments += stats.count;
175
+ totalSize += stats.size;
176
+ }
177
+ return {
178
+ db: this.dbNameFromPath,
179
+ collections: collections.length,
180
+ totalDocuments,
181
+ totalSize,
182
+ path: this.dbPath,
183
+ jsonb: this.options.jsonb
184
+ };
185
+ }
186
+ /**
187
+ * 删除数据库
188
+ */
189
+ async drop() {
190
+ if (existsSync(this.dbPath)) {
191
+ await rm(this.dbPath, { recursive: true, force: true });
192
+ }
193
+ this._meta = null;
194
+ this._collections.clear();
195
+ return { acknowledged: true };
196
+ }
197
+ }
198
+ //# sourceMappingURL=Database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Database.js","sourceRoot":"","sources":["../../src/Database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAkC3E;;;GAGG;AACH,MAAM,OAAO,QAAQ;IACnB,MAAM,CAAS;IACP,SAAS,CAAS;IAClB,KAAK,CAAsB;IAC3B,YAAY,CAA0B;IAC9C,OAAO,CAKL;IAEF;;;OAGG;IACH,YAAY,MAAc,EAAE,UAA2B,EAAE;QACvD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG;YACb,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK;YAC7B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;YAClC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,KAAK,KAAK;YACpD,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,KAAK;SAC9C,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,eAAe;QACf,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,IAAI,CAAC,KAAK,GAAG;gBACX,IAAI,EAAE,IAAI,CAAC,cAAc;gBACzB,OAAO,EAAE,OAAO;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,WAAW,EAAE,EAAE;aAChB,CAAC;YACF,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,QAAQ;YACR,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;IACvD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS;QACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAiB,CAAC;IACnD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS;QACrB,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACpD,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,WAAW;QACX,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;YACpD,mBAAmB;QACrB,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,IAAY;QACrB,OAAO;QACP,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;QACtC,CAAC;QAED,QAAQ;QACR,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAExC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,UAAmC,EAAE;QACxE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;QAEzD,YAAY;QACZ,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,SAAS;QACT,MAAM,WAAW,GAAG;YAClB,KAAK,EAAE;gBACL,IAAI;gBACJ,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;aAC/B;YACD,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb,CAAC;QAEF,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1B,MAAM,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAE/E,QAAQ;QACR,IAAI,CAAC,IAAI,CAAC,KAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACzB,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAExC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,IAAY;QAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;QAEzD,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;QACjC,CAAC;QAED,OAAO;QACP,MAAM,EAAE,CAAC,cAAc,CAAC,CAAC;QAEzB,QAAQ;QACR,IAAI,CAAC,KAAM,CAAC,WAAW,GAAG,IAAI,CAAC,KAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC1E,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAEvB,OAAO;QACP,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE/B,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,iBAAiB;QACjB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,eAAe,GAAG,KAAK;aAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,YAAY,CAAC;aAC/D,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAE1C,OAAO,eAAe,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QACjD,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;YACvC,cAAc,IAAI,KAAK,CAAC,KAAK,CAAC;YAC9B,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC;QAC1B,CAAC;QAED,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,cAAc;YACvB,WAAW,EAAE,WAAW,CAAC,MAAM;YAC/B,cAAc;YACd,SAAS;YACT,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;SAC1B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAE1B,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * 查询和操作符实现
3
+ */
4
+ /**
5
+ * 比较操作符
6
+ */
7
+ export declare const comparisonOperators: {
8
+ $eq: (value: unknown, queryValue: unknown) => boolean;
9
+ $ne: (value: unknown, queryValue: unknown) => boolean;
10
+ $gt: (value: unknown, queryValue: unknown) => boolean;
11
+ $gte: (value: unknown, queryValue: unknown) => boolean;
12
+ $lt: (value: unknown, queryValue: unknown) => boolean;
13
+ $lte: (value: unknown, queryValue: unknown) => boolean;
14
+ $in: (value: unknown, queryValue: unknown) => boolean;
15
+ $nin: (value: unknown, queryValue: unknown) => boolean;
16
+ };
17
+ /**
18
+ * 逻辑操作符
19
+ */
20
+ export declare const logicalOperators: {
21
+ $and: (doc: Record<string, unknown>, conditions: Record<string, unknown>[]) => boolean;
22
+ $or: (doc: Record<string, unknown>, conditions: Record<string, unknown>[]) => boolean;
23
+ $nor: (doc: Record<string, unknown>, conditions: Record<string, unknown>[]) => boolean;
24
+ $not: (doc: Record<string, unknown>, condition: Record<string, unknown>, field?: string) => boolean;
25
+ };
26
+ /**
27
+ * 元素操作符
28
+ */
29
+ export declare const elementOperators: {
30
+ $exists: (value: unknown, queryValue: boolean) => boolean;
31
+ $type: (value: unknown, queryValue: string) => boolean;
32
+ };
33
+ /**
34
+ * 数组操作符
35
+ */
36
+ export declare const arrayOperators: {
37
+ $all: (value: unknown, queryValue: unknown[]) => boolean;
38
+ $elemMatch: (value: unknown, queryValue: Record<string, unknown> | unknown) => boolean;
39
+ $size: (value: unknown, queryValue: number) => boolean;
40
+ };
41
+ /**
42
+ * 正则表达式操作符
43
+ */
44
+ export declare function matchRegex(value: unknown, options: {
45
+ $regex: string | RegExp;
46
+ $options?: string;
47
+ }): boolean;
48
+ /**
49
+ * 匹配查询条件
50
+ */
51
+ export declare function matchQuery(doc: Record<string, unknown>, query: Record<string, unknown>): boolean;
52
+ /**
53
+ * 更新操作符实现
54
+ */
55
+ export declare const updateOperators: {
56
+ $set: (doc: Record<string, unknown>, updates: Record<string, unknown>) => void;
57
+ $unset: (doc: Record<string, unknown>, paths: Record<string, unknown>) => void;
58
+ $inc: (doc: Record<string, unknown>, updates: Record<string, number>) => void;
59
+ $mul: (doc: Record<string, unknown>, updates: Record<string, number>) => void;
60
+ $rename: (doc: Record<string, unknown>, renames: Record<string, string>) => void;
61
+ $setOnInsert: (doc: Record<string, unknown>, updates: Record<string, unknown>, isInsert: boolean) => void;
62
+ $min: (doc: Record<string, unknown>, updates: Record<string, number>) => void;
63
+ $max: (doc: Record<string, unknown>, updates: Record<string, number>) => void;
64
+ $push: (doc: Record<string, unknown>, updates: Record<string, unknown>) => void;
65
+ $pop: (doc: Record<string, unknown>, updates: Record<string, number>) => void;
66
+ $pull: (doc: Record<string, unknown>, updates: Record<string, unknown>) => void;
67
+ $addToSet: (doc: Record<string, unknown>, updates: Record<string, unknown>) => void;
68
+ };
69
+ /**
70
+ * 应用更新到文档
71
+ */
72
+ export declare function applyUpdate(doc: Record<string, unknown>, update: Record<string, unknown>, isInsert?: boolean): Record<string, unknown>;
73
+ //# sourceMappingURL=Operators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Operators.d.ts","sourceRoot":"","sources":["../../src/Operators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,339 @@
1
+ /**
2
+ * 查询和操作符实现
3
+ */
4
+ import { getNestedValue, isType, setNestedValue, deleteNestedValue } from './Utils.js';
5
+ /**
6
+ * 比较操作符
7
+ */
8
+ export const comparisonOperators = {
9
+ $eq: (value, queryValue) => value === queryValue,
10
+ $ne: (value, queryValue) => value !== queryValue,
11
+ $gt: (value, queryValue) => value > queryValue,
12
+ $gte: (value, queryValue) => value >= queryValue,
13
+ $lt: (value, queryValue) => value < queryValue,
14
+ $lte: (value, queryValue) => value <= queryValue,
15
+ $in: (value, queryValue) => {
16
+ if (!Array.isArray(queryValue)) {
17
+ throw new Error('$in 操作符需要数组');
18
+ }
19
+ return queryValue.includes(value);
20
+ },
21
+ $nin: (value, queryValue) => {
22
+ if (!Array.isArray(queryValue)) {
23
+ throw new Error('$nin 操作符需要数组');
24
+ }
25
+ return !queryValue.includes(value);
26
+ }
27
+ };
28
+ /**
29
+ * 逻辑操作符
30
+ */
31
+ export const logicalOperators = {
32
+ $and: (doc, conditions) => {
33
+ if (!Array.isArray(conditions)) {
34
+ throw new Error('$and 操作符需要数组');
35
+ }
36
+ return conditions.every(condition => matchQuery(doc, condition));
37
+ },
38
+ $or: (doc, conditions) => {
39
+ if (!Array.isArray(conditions)) {
40
+ throw new Error('$or 操作符需要数组');
41
+ }
42
+ return conditions.some(condition => matchQuery(doc, condition));
43
+ },
44
+ $nor: (doc, conditions) => {
45
+ if (!Array.isArray(conditions)) {
46
+ throw new Error('$nor 操作符需要数组');
47
+ }
48
+ return !conditions.some(condition => matchQuery(doc, condition));
49
+ },
50
+ $not: (doc, condition, field) => {
51
+ return !matchField(doc, field, condition);
52
+ }
53
+ };
54
+ /**
55
+ * 元素操作符
56
+ */
57
+ export const elementOperators = {
58
+ $exists: (value, queryValue) => {
59
+ return queryValue ? value !== undefined : value === undefined;
60
+ },
61
+ $type: (value, queryValue) => {
62
+ return isType(value, queryValue);
63
+ }
64
+ };
65
+ /**
66
+ * 数组操作符
67
+ */
68
+ export const arrayOperators = {
69
+ $all: (value, queryValue) => {
70
+ if (!Array.isArray(value)) {
71
+ return false;
72
+ }
73
+ if (!Array.isArray(queryValue)) {
74
+ throw new Error('$all 操作符需要数组');
75
+ }
76
+ return queryValue.every(item => value.includes(item));
77
+ },
78
+ $elemMatch: (value, queryValue) => {
79
+ if (!Array.isArray(value)) {
80
+ return false;
81
+ }
82
+ // 处理数组元素匹配
83
+ return value.some(item => {
84
+ // 如果 queryValue 是对象,需要匹配所有条件
85
+ if (typeof queryValue === 'object' && queryValue !== null) {
86
+ for (const [key, condition] of Object.entries(queryValue)) {
87
+ const itemValue = item[key] !== undefined
88
+ ? item[key]
89
+ : (typeof key === 'string' && item[key] !== undefined
90
+ ? item[key]
91
+ : undefined);
92
+ if (typeof condition === 'object' && condition !== null) {
93
+ // 处理操作符条件
94
+ for (const [op, opValue] of Object.entries(condition)) {
95
+ if (op === '$gte' && !(itemValue >= opValue))
96
+ return false;
97
+ if (op === '$lte' && !(itemValue <= opValue))
98
+ return false;
99
+ if (op === '$gt' && !(itemValue > opValue))
100
+ return false;
101
+ if (op === '$lt' && !(itemValue < opValue))
102
+ return false;
103
+ if (op === '$eq' && !(itemValue === opValue))
104
+ return false;
105
+ if (op === '$ne' && !(itemValue !== opValue))
106
+ return false;
107
+ }
108
+ }
109
+ else if (itemValue !== condition) {
110
+ return false;
111
+ }
112
+ }
113
+ return true;
114
+ }
115
+ return item === queryValue;
116
+ });
117
+ },
118
+ $size: (value, queryValue) => {
119
+ if (!Array.isArray(value)) {
120
+ return false;
121
+ }
122
+ return value.length === queryValue;
123
+ }
124
+ };
125
+ /**
126
+ * 正则表达式操作符
127
+ */
128
+ export function matchRegex(value, options) {
129
+ if (typeof value !== 'string') {
130
+ return false;
131
+ }
132
+ const { $regex, $options = '' } = options;
133
+ try {
134
+ const regex = typeof $regex === 'string' ? new RegExp($regex, $options) : $regex;
135
+ return regex.test(value);
136
+ }
137
+ catch (e) {
138
+ throw new Error(`无效的正则表达式:${$regex}`);
139
+ }
140
+ }
141
+ /**
142
+ * 匹配字段值
143
+ */
144
+ function matchField(doc, field, condition) {
145
+ const value = getNestedValue(doc, field);
146
+ // 如果条件是普通值,直接比较
147
+ if (!condition || typeof condition !== 'object') {
148
+ return value === condition;
149
+ }
150
+ // 处理操作符
151
+ let hasOperatorMatch = false;
152
+ for (const [operator, queryValue] of Object.entries(condition)) {
153
+ if (operator.startsWith('$')) {
154
+ // $options 是 $regex 的修饰符,跳过
155
+ if (operator === '$options') {
156
+ continue;
157
+ }
158
+ hasOperatorMatch = true;
159
+ let result;
160
+ // 比较操作符
161
+ if (comparisonOperators[operator]) {
162
+ result = comparisonOperators[operator](value, queryValue);
163
+ }
164
+ // 元素操作符
165
+ else if (elementOperators[operator]) {
166
+ result = elementOperators[operator](value, queryValue);
167
+ }
168
+ // 数组操作符
169
+ else if (arrayOperators[operator]) {
170
+ result = arrayOperators[operator](value, queryValue);
171
+ }
172
+ // 正则操作符
173
+ else if (operator === '$regex') {
174
+ result = matchRegex(value, condition);
175
+ }
176
+ // 未知操作符
177
+ else {
178
+ throw new Error(`未知操作符:${operator}`);
179
+ }
180
+ if (!result) {
181
+ return false;
182
+ }
183
+ }
184
+ }
185
+ // 如果没有操作符匹配,直接比较值
186
+ if (!hasOperatorMatch) {
187
+ return value === condition;
188
+ }
189
+ return true;
190
+ }
191
+ /**
192
+ * 匹配查询条件
193
+ */
194
+ export function matchQuery(doc, query) {
195
+ if (!query || typeof query !== 'object') {
196
+ return true;
197
+ }
198
+ for (const [key, condition] of Object.entries(query)) {
199
+ // 逻辑操作符
200
+ if (key.startsWith('$')) {
201
+ if (logicalOperators[key]) {
202
+ const result = logicalOperators[key](doc, condition);
203
+ if (!result) {
204
+ return false;
205
+ }
206
+ }
207
+ else {
208
+ throw new Error(`未知逻辑操作符:${key}`);
209
+ }
210
+ }
211
+ else {
212
+ // 字段匹配
213
+ const result = matchField(doc, key, condition);
214
+ if (!result) {
215
+ return false;
216
+ }
217
+ }
218
+ }
219
+ return true;
220
+ }
221
+ /**
222
+ * 更新操作符实现
223
+ */
224
+ export const updateOperators = {
225
+ $set: (doc, updates) => {
226
+ for (const [path, value] of Object.entries(updates)) {
227
+ setNestedValue(doc, path, value);
228
+ }
229
+ },
230
+ $unset: (doc, paths) => {
231
+ for (const path of Object.keys(paths)) {
232
+ deleteNestedValue(doc, path);
233
+ }
234
+ },
235
+ $inc: (doc, updates) => {
236
+ for (const [path, value] of Object.entries(updates)) {
237
+ const currentValue = getNestedValue(doc, path) || 0;
238
+ setNestedValue(doc, path, currentValue + value);
239
+ }
240
+ },
241
+ $mul: (doc, updates) => {
242
+ for (const [path, value] of Object.entries(updates)) {
243
+ const currentValue = getNestedValue(doc, path) || 1;
244
+ setNestedValue(doc, path, currentValue * value);
245
+ }
246
+ },
247
+ $rename: (doc, renames) => {
248
+ for (const [oldPath, newPath] of Object.entries(renames)) {
249
+ const value = getNestedValue(doc, oldPath);
250
+ if (value !== undefined) {
251
+ setNestedValue(doc, newPath, value);
252
+ deleteNestedValue(doc, oldPath);
253
+ }
254
+ }
255
+ },
256
+ $setOnInsert: (doc, updates, isInsert) => {
257
+ if (isInsert) {
258
+ updateOperators.$set(doc, updates);
259
+ }
260
+ },
261
+ $min: (doc, updates) => {
262
+ for (const [path, value] of Object.entries(updates)) {
263
+ const currentValue = getNestedValue(doc, path);
264
+ if (currentValue === undefined || value < currentValue) {
265
+ setNestedValue(doc, path, value);
266
+ }
267
+ }
268
+ },
269
+ $max: (doc, updates) => {
270
+ for (const [path, value] of Object.entries(updates)) {
271
+ const currentValue = getNestedValue(doc, path);
272
+ if (currentValue === undefined || value > currentValue) {
273
+ setNestedValue(doc, path, value);
274
+ }
275
+ }
276
+ },
277
+ $push: (doc, updates) => {
278
+ for (const [path, value] of Object.entries(updates)) {
279
+ const currentValue = getNestedValue(doc, path);
280
+ const array = Array.isArray(currentValue) ? currentValue : [];
281
+ setNestedValue(doc, path, [...array, value]);
282
+ }
283
+ },
284
+ $pop: (doc, updates) => {
285
+ for (const [path, direction] of Object.entries(updates)) {
286
+ const currentValue = getNestedValue(doc, path);
287
+ if (Array.isArray(currentValue) && currentValue.length > 0) {
288
+ if (direction === 1) {
289
+ setNestedValue(doc, path, currentValue.slice(0, -1));
290
+ }
291
+ else if (direction === -1) {
292
+ setNestedValue(doc, path, currentValue.slice(1));
293
+ }
294
+ }
295
+ }
296
+ },
297
+ $pull: (doc, updates) => {
298
+ for (const [path, condition] of Object.entries(updates)) {
299
+ const currentValue = getNestedValue(doc, path);
300
+ if (Array.isArray(currentValue)) {
301
+ const filtered = currentValue.filter(item => {
302
+ if (typeof condition === 'object') {
303
+ return !matchQuery(item, condition);
304
+ }
305
+ return item !== condition;
306
+ });
307
+ setNestedValue(doc, path, filtered);
308
+ }
309
+ }
310
+ },
311
+ $addToSet: (doc, updates) => {
312
+ for (const [path, value] of Object.entries(updates)) {
313
+ const currentValue = getNestedValue(doc, path);
314
+ const array = Array.isArray(currentValue) ? currentValue : [];
315
+ if (!array.some(item => JSON.stringify(item) === JSON.stringify(value))) {
316
+ setNestedValue(doc, path, [...array, value]);
317
+ }
318
+ }
319
+ }
320
+ };
321
+ /**
322
+ * 应用更新到文档
323
+ */
324
+ export function applyUpdate(doc, update, isInsert = false) {
325
+ const result = JSON.parse(JSON.stringify(doc));
326
+ for (const [operator, updates] of Object.entries(update)) {
327
+ if (!operator.startsWith('$')) {
328
+ throw new Error('更新操作必须使用操作符');
329
+ }
330
+ if (updateOperators[operator]) {
331
+ updateOperators[operator](result, updates, isInsert);
332
+ }
333
+ else {
334
+ throw new Error(`未知更新操作符:${operator}`);
335
+ }
336
+ }
337
+ return result;
338
+ }
339
+ //# sourceMappingURL=Operators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Operators.js","sourceRoot":"","sources":["../../src/Operators.ts"],"names":[],"mappings":"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"}