@push.rocks/smartmongo 2.2.0 → 4.0.0

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 (126) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/index.d.ts +1 -1
  3. package/dist_ts/index.js +3 -3
  4. package/dist_ts/tsmdb/engine/AggregationEngine.js +189 -0
  5. package/dist_ts/{congodb → tsmdb}/engine/IndexEngine.d.ts +23 -3
  6. package/dist_ts/tsmdb/engine/IndexEngine.js +678 -0
  7. package/dist_ts/tsmdb/engine/QueryEngine.js +271 -0
  8. package/dist_ts/tsmdb/engine/QueryPlanner.d.ts +64 -0
  9. package/dist_ts/tsmdb/engine/QueryPlanner.js +308 -0
  10. package/dist_ts/tsmdb/engine/SessionEngine.d.ts +117 -0
  11. package/dist_ts/tsmdb/engine/SessionEngine.js +232 -0
  12. package/dist_ts/{congodb → tsmdb}/engine/TransactionEngine.d.ts +1 -1
  13. package/dist_ts/tsmdb/engine/TransactionEngine.js +287 -0
  14. package/dist_ts/tsmdb/engine/UpdateEngine.js +461 -0
  15. package/dist_ts/{congodb/errors/CongoErrors.d.ts → tsmdb/errors/TsmdbErrors.d.ts} +16 -16
  16. package/dist_ts/tsmdb/errors/TsmdbErrors.js +155 -0
  17. package/dist_ts/{congodb → tsmdb}/index.d.ts +11 -4
  18. package/dist_ts/tsmdb/index.js +31 -0
  19. package/dist_ts/tsmdb/server/CommandRouter.d.ts +87 -0
  20. package/dist_ts/tsmdb/server/CommandRouter.js +222 -0
  21. package/dist_ts/{congodb/server/CongoServer.d.ts → tsmdb/server/TsmdbServer.d.ts} +6 -6
  22. package/dist_ts/tsmdb/server/TsmdbServer.js +229 -0
  23. package/dist_ts/{congodb → tsmdb}/server/WireProtocol.d.ts +1 -1
  24. package/dist_ts/tsmdb/server/WireProtocol.js +298 -0
  25. package/dist_ts/{congodb → tsmdb}/server/handlers/AdminHandler.d.ts +1 -1
  26. package/dist_ts/tsmdb/server/handlers/AdminHandler.js +668 -0
  27. package/dist_ts/{congodb → tsmdb}/server/handlers/AggregateHandler.d.ts +1 -1
  28. package/dist_ts/tsmdb/server/handlers/AggregateHandler.js +277 -0
  29. package/dist_ts/{congodb → tsmdb}/server/handlers/DeleteHandler.d.ts +1 -1
  30. package/dist_ts/tsmdb/server/handlers/DeleteHandler.js +95 -0
  31. package/dist_ts/{congodb → tsmdb}/server/handlers/FindHandler.d.ts +1 -1
  32. package/dist_ts/tsmdb/server/handlers/FindHandler.js +291 -0
  33. package/dist_ts/{congodb → tsmdb}/server/handlers/HelloHandler.d.ts +1 -1
  34. package/dist_ts/{congodb → tsmdb}/server/handlers/HelloHandler.js +2 -2
  35. package/dist_ts/{congodb → tsmdb}/server/handlers/IndexHandler.d.ts +1 -1
  36. package/dist_ts/tsmdb/server/handlers/IndexHandler.js +183 -0
  37. package/dist_ts/{congodb → tsmdb}/server/handlers/InsertHandler.d.ts +1 -1
  38. package/dist_ts/tsmdb/server/handlers/InsertHandler.js +79 -0
  39. package/dist_ts/{congodb → tsmdb}/server/handlers/UpdateHandler.d.ts +1 -1
  40. package/dist_ts/tsmdb/server/handlers/UpdateHandler.js +296 -0
  41. package/dist_ts/tsmdb/server/handlers/index.js +10 -0
  42. package/dist_ts/{congodb → tsmdb}/server/index.d.ts +2 -2
  43. package/dist_ts/tsmdb/server/index.js +7 -0
  44. package/dist_ts/{congodb → tsmdb}/storage/FileStorageAdapter.d.ts +27 -3
  45. package/dist_ts/tsmdb/storage/FileStorageAdapter.js +465 -0
  46. package/dist_ts/{congodb → tsmdb}/storage/IStorageAdapter.d.ts +7 -2
  47. package/dist_ts/{congodb → tsmdb}/storage/IStorageAdapter.js +1 -1
  48. package/dist_ts/{congodb → tsmdb}/storage/MemoryStorageAdapter.d.ts +3 -2
  49. package/dist_ts/tsmdb/storage/MemoryStorageAdapter.js +378 -0
  50. package/dist_ts/{congodb → tsmdb}/storage/OpLog.d.ts +1 -1
  51. package/dist_ts/tsmdb/storage/OpLog.js +221 -0
  52. package/dist_ts/tsmdb/storage/WAL.d.ts +117 -0
  53. package/dist_ts/tsmdb/storage/WAL.js +286 -0
  54. package/dist_ts/tsmdb/tsmdb.plugins.js +14 -0
  55. package/dist_ts/{congodb → tsmdb}/types/interfaces.d.ts +3 -3
  56. package/dist_ts/{congodb → tsmdb}/types/interfaces.js +1 -1
  57. package/dist_ts/tsmdb/utils/checksum.d.ts +30 -0
  58. package/dist_ts/tsmdb/utils/checksum.js +77 -0
  59. package/dist_ts/tsmdb/utils/index.d.ts +1 -0
  60. package/dist_ts/tsmdb/utils/index.js +2 -0
  61. package/package.json +1 -1
  62. package/readme.hints.md +7 -12
  63. package/readme.md +25 -25
  64. package/ts/00_commitinfo_data.ts +1 -1
  65. package/ts/index.ts +2 -2
  66. package/ts/{congodb → tsmdb}/engine/AggregationEngine.ts +1 -1
  67. package/ts/tsmdb/engine/IndexEngine.ts +798 -0
  68. package/ts/{congodb → tsmdb}/engine/QueryEngine.ts +1 -1
  69. package/ts/tsmdb/engine/QueryPlanner.ts +393 -0
  70. package/ts/tsmdb/engine/SessionEngine.ts +292 -0
  71. package/ts/{congodb → tsmdb}/engine/TransactionEngine.ts +12 -12
  72. package/ts/{congodb → tsmdb}/engine/UpdateEngine.ts +1 -1
  73. package/ts/{congodb/errors/CongoErrors.ts → tsmdb/errors/TsmdbErrors.ts} +34 -34
  74. package/ts/{congodb → tsmdb}/index.ts +16 -7
  75. package/ts/{congodb → tsmdb}/server/CommandRouter.ts +114 -5
  76. package/ts/{congodb/server/CongoServer.ts → tsmdb/server/TsmdbServer.ts} +11 -8
  77. package/ts/{congodb → tsmdb}/server/WireProtocol.ts +1 -1
  78. package/ts/{congodb → tsmdb}/server/handlers/AdminHandler.ts +116 -11
  79. package/ts/{congodb → tsmdb}/server/handlers/AggregateHandler.ts +1 -1
  80. package/ts/{congodb → tsmdb}/server/handlers/DeleteHandler.ts +18 -3
  81. package/ts/{congodb → tsmdb}/server/handlers/FindHandler.ts +43 -14
  82. package/ts/{congodb → tsmdb}/server/handlers/HelloHandler.ts +1 -1
  83. package/ts/{congodb → tsmdb}/server/handlers/IndexHandler.ts +1 -1
  84. package/ts/{congodb → tsmdb}/server/handlers/InsertHandler.ts +7 -1
  85. package/ts/{congodb → tsmdb}/server/handlers/UpdateHandler.ts +34 -5
  86. package/ts/{congodb → tsmdb}/server/index.ts +2 -2
  87. package/ts/{congodb → tsmdb}/storage/FileStorageAdapter.ts +90 -7
  88. package/ts/{congodb → tsmdb}/storage/IStorageAdapter.ts +8 -2
  89. package/ts/{congodb → tsmdb}/storage/MemoryStorageAdapter.ts +14 -2
  90. package/ts/{congodb → tsmdb}/storage/OpLog.ts +1 -1
  91. package/ts/tsmdb/storage/WAL.ts +375 -0
  92. package/ts/{congodb → tsmdb}/types/interfaces.ts +3 -3
  93. package/ts/tsmdb/utils/checksum.ts +88 -0
  94. package/ts/tsmdb/utils/index.ts +1 -0
  95. package/dist_ts/congodb/congodb.plugins.js +0 -14
  96. package/dist_ts/congodb/engine/AggregationEngine.js +0 -189
  97. package/dist_ts/congodb/engine/IndexEngine.js +0 -376
  98. package/dist_ts/congodb/engine/QueryEngine.js +0 -271
  99. package/dist_ts/congodb/engine/TransactionEngine.js +0 -287
  100. package/dist_ts/congodb/engine/UpdateEngine.js +0 -461
  101. package/dist_ts/congodb/errors/CongoErrors.js +0 -155
  102. package/dist_ts/congodb/index.js +0 -26
  103. package/dist_ts/congodb/server/CommandRouter.d.ts +0 -51
  104. package/dist_ts/congodb/server/CommandRouter.js +0 -132
  105. package/dist_ts/congodb/server/CongoServer.js +0 -227
  106. package/dist_ts/congodb/server/WireProtocol.js +0 -298
  107. package/dist_ts/congodb/server/handlers/AdminHandler.js +0 -568
  108. package/dist_ts/congodb/server/handlers/AggregateHandler.js +0 -277
  109. package/dist_ts/congodb/server/handlers/DeleteHandler.js +0 -83
  110. package/dist_ts/congodb/server/handlers/FindHandler.js +0 -261
  111. package/dist_ts/congodb/server/handlers/IndexHandler.js +0 -183
  112. package/dist_ts/congodb/server/handlers/InsertHandler.js +0 -76
  113. package/dist_ts/congodb/server/handlers/UpdateHandler.js +0 -270
  114. package/dist_ts/congodb/server/handlers/index.js +0 -10
  115. package/dist_ts/congodb/server/index.js +0 -7
  116. package/dist_ts/congodb/storage/FileStorageAdapter.js +0 -396
  117. package/dist_ts/congodb/storage/MemoryStorageAdapter.js +0 -367
  118. package/dist_ts/congodb/storage/OpLog.js +0 -221
  119. package/ts/congodb/engine/IndexEngine.ts +0 -479
  120. /package/dist_ts/{congodb → tsmdb}/engine/AggregationEngine.d.ts +0 -0
  121. /package/dist_ts/{congodb → tsmdb}/engine/QueryEngine.d.ts +0 -0
  122. /package/dist_ts/{congodb → tsmdb}/engine/UpdateEngine.d.ts +0 -0
  123. /package/dist_ts/{congodb → tsmdb}/server/handlers/index.d.ts +0 -0
  124. /package/dist_ts/{congodb/congodb.plugins.d.ts → tsmdb/tsmdb.plugins.d.ts} +0 -0
  125. /package/ts/{congodb → tsmdb}/server/handlers/index.ts +0 -0
  126. /package/ts/{congodb/congodb.plugins.ts → tsmdb/tsmdb.plugins.ts} +0 -0
@@ -0,0 +1,668 @@
1
+ import * as plugins from '../../tsmdb.plugins.js';
2
+ import { SessionEngine } from '../../engine/SessionEngine.js';
3
+ /**
4
+ * AdminHandler - Handles administrative commands
5
+ */
6
+ export class AdminHandler {
7
+ async handle(context) {
8
+ const { command } = context;
9
+ // Determine which command to handle
10
+ if (command.ping !== undefined) {
11
+ return this.handlePing(context);
12
+ }
13
+ else if (command.listDatabases !== undefined) {
14
+ return this.handleListDatabases(context);
15
+ }
16
+ else if (command.listCollections !== undefined) {
17
+ return this.handleListCollections(context);
18
+ }
19
+ else if (command.drop !== undefined) {
20
+ return this.handleDrop(context);
21
+ }
22
+ else if (command.dropDatabase !== undefined) {
23
+ return this.handleDropDatabase(context);
24
+ }
25
+ else if (command.create !== undefined) {
26
+ return this.handleCreate(context);
27
+ }
28
+ else if (command.serverStatus !== undefined) {
29
+ return this.handleServerStatus(context);
30
+ }
31
+ else if (command.buildInfo !== undefined) {
32
+ return this.handleBuildInfo(context);
33
+ }
34
+ else if (command.whatsmyuri !== undefined) {
35
+ return this.handleWhatsMyUri(context);
36
+ }
37
+ else if (command.getLog !== undefined) {
38
+ return this.handleGetLog(context);
39
+ }
40
+ else if (command.hostInfo !== undefined) {
41
+ return this.handleHostInfo(context);
42
+ }
43
+ else if (command.replSetGetStatus !== undefined) {
44
+ return this.handleReplSetGetStatus(context);
45
+ }
46
+ else if (command.saslStart !== undefined) {
47
+ return this.handleSaslStart(context);
48
+ }
49
+ else if (command.saslContinue !== undefined) {
50
+ return this.handleSaslContinue(context);
51
+ }
52
+ else if (command.endSessions !== undefined) {
53
+ return this.handleEndSessions(context);
54
+ }
55
+ else if (command.abortTransaction !== undefined) {
56
+ return this.handleAbortTransaction(context);
57
+ }
58
+ else if (command.commitTransaction !== undefined) {
59
+ return this.handleCommitTransaction(context);
60
+ }
61
+ else if (command.collStats !== undefined) {
62
+ return this.handleCollStats(context);
63
+ }
64
+ else if (command.dbStats !== undefined) {
65
+ return this.handleDbStats(context);
66
+ }
67
+ else if (command.connectionStatus !== undefined) {
68
+ return this.handleConnectionStatus(context);
69
+ }
70
+ else if (command.currentOp !== undefined) {
71
+ return this.handleCurrentOp(context);
72
+ }
73
+ else if (command.collMod !== undefined) {
74
+ return this.handleCollMod(context);
75
+ }
76
+ else if (command.renameCollection !== undefined) {
77
+ return this.handleRenameCollection(context);
78
+ }
79
+ return {
80
+ ok: 0,
81
+ errmsg: 'Unknown admin command',
82
+ code: 59,
83
+ codeName: 'CommandNotFound',
84
+ };
85
+ }
86
+ /**
87
+ * Handle ping command
88
+ */
89
+ async handlePing(context) {
90
+ return { ok: 1 };
91
+ }
92
+ /**
93
+ * Handle listDatabases command
94
+ */
95
+ async handleListDatabases(context) {
96
+ const { storage, command } = context;
97
+ const dbNames = await storage.listDatabases();
98
+ const nameOnly = command.nameOnly || false;
99
+ if (nameOnly) {
100
+ return {
101
+ ok: 1,
102
+ databases: dbNames.map(name => ({ name })),
103
+ };
104
+ }
105
+ // Build database list with sizes
106
+ const databases = [];
107
+ let totalSize = 0;
108
+ for (const name of dbNames) {
109
+ const collections = await storage.listCollections(name);
110
+ let dbSize = 0;
111
+ for (const collName of collections) {
112
+ const docs = await storage.findAll(name, collName);
113
+ // Estimate size (rough approximation)
114
+ dbSize += docs.reduce((sum, doc) => sum + JSON.stringify(doc).length, 0);
115
+ }
116
+ totalSize += dbSize;
117
+ databases.push({
118
+ name,
119
+ sizeOnDisk: dbSize,
120
+ empty: dbSize === 0,
121
+ });
122
+ }
123
+ return {
124
+ ok: 1,
125
+ databases,
126
+ totalSize,
127
+ totalSizeMb: totalSize / (1024 * 1024),
128
+ };
129
+ }
130
+ /**
131
+ * Handle listCollections command
132
+ */
133
+ async handleListCollections(context) {
134
+ const { storage, database, command } = context;
135
+ const filter = command.filter || {};
136
+ const nameOnly = command.nameOnly || false;
137
+ const cursor = command.cursor || {};
138
+ const batchSize = cursor.batchSize || 101;
139
+ const collNames = await storage.listCollections(database);
140
+ let collections = [];
141
+ for (const name of collNames) {
142
+ // Apply name filter
143
+ if (filter.name && filter.name !== name) {
144
+ // Check regex
145
+ if (filter.name.$regex) {
146
+ const regex = new RegExp(filter.name.$regex, filter.name.$options);
147
+ if (!regex.test(name))
148
+ continue;
149
+ }
150
+ else {
151
+ continue;
152
+ }
153
+ }
154
+ if (nameOnly) {
155
+ collections.push({ name });
156
+ }
157
+ else {
158
+ collections.push({
159
+ name,
160
+ type: 'collection',
161
+ options: {},
162
+ info: {
163
+ readOnly: false,
164
+ uuid: new plugins.bson.UUID(),
165
+ },
166
+ idIndex: {
167
+ v: 2,
168
+ key: { _id: 1 },
169
+ name: '_id_',
170
+ },
171
+ });
172
+ }
173
+ }
174
+ return {
175
+ ok: 1,
176
+ cursor: {
177
+ id: plugins.bson.Long.fromNumber(0),
178
+ ns: `${database}.$cmd.listCollections`,
179
+ firstBatch: collections,
180
+ },
181
+ };
182
+ }
183
+ /**
184
+ * Handle drop command (drop collection)
185
+ */
186
+ async handleDrop(context) {
187
+ const { storage, database, command } = context;
188
+ const collection = command.drop;
189
+ const existed = await storage.dropCollection(database, collection);
190
+ if (!existed) {
191
+ return {
192
+ ok: 0,
193
+ errmsg: `ns not found ${database}.${collection}`,
194
+ code: 26,
195
+ codeName: 'NamespaceNotFound',
196
+ };
197
+ }
198
+ return { ok: 1, ns: `${database}.${collection}` };
199
+ }
200
+ /**
201
+ * Handle dropDatabase command
202
+ */
203
+ async handleDropDatabase(context) {
204
+ const { storage, database } = context;
205
+ await storage.dropDatabase(database);
206
+ return { ok: 1, dropped: database };
207
+ }
208
+ /**
209
+ * Handle create command (create collection)
210
+ */
211
+ async handleCreate(context) {
212
+ const { storage, database, command } = context;
213
+ const collection = command.create;
214
+ // Check if already exists
215
+ const exists = await storage.collectionExists(database, collection);
216
+ if (exists) {
217
+ return {
218
+ ok: 0,
219
+ errmsg: `Collection ${database}.${collection} already exists.`,
220
+ code: 48,
221
+ codeName: 'NamespaceExists',
222
+ };
223
+ }
224
+ await storage.createCollection(database, collection);
225
+ return { ok: 1 };
226
+ }
227
+ /**
228
+ * Handle serverStatus command
229
+ */
230
+ async handleServerStatus(context) {
231
+ const { server, sessionEngine } = context;
232
+ const uptime = server.getUptime();
233
+ const connections = server.getConnectionCount();
234
+ const sessions = sessionEngine.listSessions();
235
+ const sessionsWithTxn = sessionEngine.getSessionsWithTransactions();
236
+ return {
237
+ ok: 1,
238
+ host: `${server.host}:${server.port}`,
239
+ version: '7.0.0',
240
+ process: 'tsmdb',
241
+ pid: process.pid,
242
+ uptime,
243
+ uptimeMillis: uptime * 1000,
244
+ uptimeEstimate: uptime,
245
+ localTime: new Date(),
246
+ mem: {
247
+ resident: Math.floor(process.memoryUsage().rss / (1024 * 1024)),
248
+ virtual: Math.floor(process.memoryUsage().heapTotal / (1024 * 1024)),
249
+ supported: true,
250
+ },
251
+ connections: {
252
+ current: connections,
253
+ available: 1000 - connections,
254
+ totalCreated: connections,
255
+ active: connections,
256
+ },
257
+ logicalSessionRecordCache: {
258
+ activeSessionsCount: sessions.length,
259
+ sessionsCollectionJobCount: 0,
260
+ lastSessionsCollectionJobDurationMillis: 0,
261
+ lastSessionsCollectionJobTimestamp: new Date(),
262
+ transactionReaperJobCount: 0,
263
+ lastTransactionReaperJobDurationMillis: 0,
264
+ lastTransactionReaperJobTimestamp: new Date(),
265
+ },
266
+ transactions: {
267
+ retriedCommandsCount: 0,
268
+ retriedStatementsCount: 0,
269
+ transactionsCollectionWriteCount: 0,
270
+ currentActive: sessionsWithTxn.length,
271
+ currentInactive: 0,
272
+ currentOpen: sessionsWithTxn.length,
273
+ totalStarted: sessionsWithTxn.length,
274
+ totalCommitted: 0,
275
+ totalAborted: 0,
276
+ },
277
+ network: {
278
+ bytesIn: 0,
279
+ bytesOut: 0,
280
+ numRequests: 0,
281
+ },
282
+ storageEngine: {
283
+ name: 'tsmdb',
284
+ supportsCommittedReads: true,
285
+ persistent: false,
286
+ },
287
+ };
288
+ }
289
+ /**
290
+ * Handle buildInfo command
291
+ */
292
+ async handleBuildInfo(context) {
293
+ return {
294
+ ok: 1,
295
+ version: '7.0.0',
296
+ gitVersion: 'tsmdb',
297
+ modules: [],
298
+ allocator: 'system',
299
+ javascriptEngine: 'none',
300
+ sysInfo: 'deprecated',
301
+ versionArray: [7, 0, 0, 0],
302
+ openssl: {
303
+ running: 'disabled',
304
+ compiled: 'disabled',
305
+ },
306
+ buildEnvironment: {
307
+ distmod: 'tsmdb',
308
+ distarch: process.arch,
309
+ cc: '',
310
+ ccflags: '',
311
+ cxx: '',
312
+ cxxflags: '',
313
+ linkflags: '',
314
+ target_arch: process.arch,
315
+ target_os: process.platform,
316
+ },
317
+ bits: 64,
318
+ debug: false,
319
+ maxBsonObjectSize: 16777216,
320
+ storageEngines: ['tsmdb'],
321
+ };
322
+ }
323
+ /**
324
+ * Handle whatsmyuri command
325
+ */
326
+ async handleWhatsMyUri(context) {
327
+ const { server } = context;
328
+ return {
329
+ ok: 1,
330
+ you: `127.0.0.1:${server.port}`,
331
+ };
332
+ }
333
+ /**
334
+ * Handle getLog command
335
+ */
336
+ async handleGetLog(context) {
337
+ const { command } = context;
338
+ if (command.getLog === '*') {
339
+ return {
340
+ ok: 1,
341
+ names: ['global', 'startupWarnings'],
342
+ };
343
+ }
344
+ return {
345
+ ok: 1,
346
+ totalLinesWritten: 0,
347
+ log: [],
348
+ };
349
+ }
350
+ /**
351
+ * Handle hostInfo command
352
+ */
353
+ async handleHostInfo(context) {
354
+ return {
355
+ ok: 1,
356
+ system: {
357
+ currentTime: new Date(),
358
+ hostname: 'localhost',
359
+ cpuAddrSize: 64,
360
+ memSizeMB: Math.floor(process.memoryUsage().heapTotal / (1024 * 1024)),
361
+ numCores: 1,
362
+ cpuArch: process.arch,
363
+ numaEnabled: false,
364
+ },
365
+ os: {
366
+ type: process.platform,
367
+ name: process.platform,
368
+ version: process.version,
369
+ },
370
+ extra: {},
371
+ };
372
+ }
373
+ /**
374
+ * Handle replSetGetStatus command
375
+ */
376
+ async handleReplSetGetStatus(context) {
377
+ // We're standalone, not a replica set
378
+ return {
379
+ ok: 0,
380
+ errmsg: 'not running with --replSet',
381
+ code: 76,
382
+ codeName: 'NoReplicationEnabled',
383
+ };
384
+ }
385
+ /**
386
+ * Handle saslStart command (authentication)
387
+ */
388
+ async handleSaslStart(context) {
389
+ // We don't require authentication, but we need to respond properly
390
+ // to let drivers know auth is "successful"
391
+ return {
392
+ ok: 1,
393
+ conversationId: 1,
394
+ done: true,
395
+ payload: Buffer.from([]),
396
+ };
397
+ }
398
+ /**
399
+ * Handle saslContinue command
400
+ */
401
+ async handleSaslContinue(context) {
402
+ return {
403
+ ok: 1,
404
+ conversationId: 1,
405
+ done: true,
406
+ payload: Buffer.from([]),
407
+ };
408
+ }
409
+ /**
410
+ * Handle endSessions command
411
+ */
412
+ async handleEndSessions(context) {
413
+ const { command, sessionEngine } = context;
414
+ // End each session in the array
415
+ const sessions = command.endSessions || [];
416
+ for (const sessionSpec of sessions) {
417
+ const sessionId = SessionEngine.extractSessionId(sessionSpec);
418
+ if (sessionId) {
419
+ await sessionEngine.endSession(sessionId);
420
+ }
421
+ }
422
+ return { ok: 1 };
423
+ }
424
+ /**
425
+ * Handle abortTransaction command
426
+ */
427
+ async handleAbortTransaction(context) {
428
+ const { transactionEngine, sessionEngine, txnId, sessionId } = context;
429
+ if (!txnId) {
430
+ return {
431
+ ok: 0,
432
+ errmsg: 'No transaction started',
433
+ code: 251,
434
+ codeName: 'NoSuchTransaction',
435
+ };
436
+ }
437
+ try {
438
+ await transactionEngine.abortTransaction(txnId);
439
+ transactionEngine.endTransaction(txnId);
440
+ // Update session state
441
+ if (sessionId) {
442
+ sessionEngine.endTransaction(sessionId);
443
+ }
444
+ return { ok: 1 };
445
+ }
446
+ catch (error) {
447
+ return {
448
+ ok: 0,
449
+ errmsg: error.message || 'Abort transaction failed',
450
+ code: error.code || 1,
451
+ codeName: error.codeName || 'UnknownError',
452
+ };
453
+ }
454
+ }
455
+ /**
456
+ * Handle commitTransaction command
457
+ */
458
+ async handleCommitTransaction(context) {
459
+ const { transactionEngine, sessionEngine, txnId, sessionId } = context;
460
+ if (!txnId) {
461
+ return {
462
+ ok: 0,
463
+ errmsg: 'No transaction started',
464
+ code: 251,
465
+ codeName: 'NoSuchTransaction',
466
+ };
467
+ }
468
+ try {
469
+ await transactionEngine.commitTransaction(txnId);
470
+ transactionEngine.endTransaction(txnId);
471
+ // Update session state
472
+ if (sessionId) {
473
+ sessionEngine.endTransaction(sessionId);
474
+ }
475
+ return { ok: 1 };
476
+ }
477
+ catch (error) {
478
+ // If commit fails, transaction should be aborted
479
+ try {
480
+ await transactionEngine.abortTransaction(txnId);
481
+ transactionEngine.endTransaction(txnId);
482
+ if (sessionId) {
483
+ sessionEngine.endTransaction(sessionId);
484
+ }
485
+ }
486
+ catch {
487
+ // Ignore abort errors
488
+ }
489
+ if (error.code === 112) {
490
+ // Write conflict
491
+ return {
492
+ ok: 0,
493
+ errmsg: error.message || 'Write conflict during commit',
494
+ code: 112,
495
+ codeName: 'WriteConflict',
496
+ };
497
+ }
498
+ return {
499
+ ok: 0,
500
+ errmsg: error.message || 'Commit transaction failed',
501
+ code: error.code || 1,
502
+ codeName: error.codeName || 'UnknownError',
503
+ };
504
+ }
505
+ }
506
+ /**
507
+ * Handle collStats command
508
+ */
509
+ async handleCollStats(context) {
510
+ const { storage, database, command } = context;
511
+ const collection = command.collStats;
512
+ const exists = await storage.collectionExists(database, collection);
513
+ if (!exists) {
514
+ return {
515
+ ok: 0,
516
+ errmsg: `ns not found ${database}.${collection}`,
517
+ code: 26,
518
+ codeName: 'NamespaceNotFound',
519
+ };
520
+ }
521
+ const docs = await storage.findAll(database, collection);
522
+ const size = docs.reduce((sum, doc) => sum + JSON.stringify(doc).length, 0);
523
+ const count = docs.length;
524
+ const avgObjSize = count > 0 ? size / count : 0;
525
+ const indexes = await storage.getIndexes(database, collection);
526
+ return {
527
+ ok: 1,
528
+ ns: `${database}.${collection}`,
529
+ count,
530
+ size,
531
+ avgObjSize,
532
+ storageSize: size,
533
+ totalIndexSize: 0,
534
+ indexSizes: indexes.reduce((acc, idx) => {
535
+ acc[idx.name] = 0;
536
+ return acc;
537
+ }, {}),
538
+ nindexes: indexes.length,
539
+ };
540
+ }
541
+ /**
542
+ * Handle dbStats command
543
+ */
544
+ async handleDbStats(context) {
545
+ const { storage, database } = context;
546
+ const collections = await storage.listCollections(database);
547
+ let totalSize = 0;
548
+ let totalObjects = 0;
549
+ for (const collName of collections) {
550
+ const docs = await storage.findAll(database, collName);
551
+ totalObjects += docs.length;
552
+ totalSize += docs.reduce((sum, doc) => sum + JSON.stringify(doc).length, 0);
553
+ }
554
+ return {
555
+ ok: 1,
556
+ db: database,
557
+ collections: collections.length,
558
+ views: 0,
559
+ objects: totalObjects,
560
+ avgObjSize: totalObjects > 0 ? totalSize / totalObjects : 0,
561
+ dataSize: totalSize,
562
+ storageSize: totalSize,
563
+ indexes: collections.length, // At least _id index per collection
564
+ indexSize: 0,
565
+ totalSize,
566
+ };
567
+ }
568
+ /**
569
+ * Handle connectionStatus command
570
+ */
571
+ async handleConnectionStatus(context) {
572
+ return {
573
+ ok: 1,
574
+ authInfo: {
575
+ authenticatedUsers: [],
576
+ authenticatedUserRoles: [],
577
+ },
578
+ };
579
+ }
580
+ /**
581
+ * Handle currentOp command
582
+ */
583
+ async handleCurrentOp(context) {
584
+ return {
585
+ ok: 1,
586
+ inprog: [],
587
+ };
588
+ }
589
+ /**
590
+ * Handle collMod command
591
+ */
592
+ async handleCollMod(context) {
593
+ // We don't support modifying collection options, but acknowledge the command
594
+ return { ok: 1 };
595
+ }
596
+ /**
597
+ * Handle renameCollection command
598
+ */
599
+ async handleRenameCollection(context) {
600
+ const { storage, command } = context;
601
+ const from = command.renameCollection;
602
+ const to = command.to;
603
+ const dropTarget = command.dropTarget || false;
604
+ if (!from || !to) {
605
+ return {
606
+ ok: 0,
607
+ errmsg: 'renameCollection requires both source and target',
608
+ code: 2,
609
+ codeName: 'BadValue',
610
+ };
611
+ }
612
+ // Parse namespace (format: "db.collection")
613
+ const fromParts = from.split('.');
614
+ const toParts = to.split('.');
615
+ if (fromParts.length < 2 || toParts.length < 2) {
616
+ return {
617
+ ok: 0,
618
+ errmsg: 'Invalid namespace format',
619
+ code: 73,
620
+ codeName: 'InvalidNamespace',
621
+ };
622
+ }
623
+ const fromDb = fromParts[0];
624
+ const fromColl = fromParts.slice(1).join('.');
625
+ const toDb = toParts[0];
626
+ const toColl = toParts.slice(1).join('.');
627
+ // Check if source exists
628
+ const sourceExists = await storage.collectionExists(fromDb, fromColl);
629
+ if (!sourceExists) {
630
+ return {
631
+ ok: 0,
632
+ errmsg: `source namespace ${from} does not exist`,
633
+ code: 26,
634
+ codeName: 'NamespaceNotFound',
635
+ };
636
+ }
637
+ // Check if target exists
638
+ const targetExists = await storage.collectionExists(toDb, toColl);
639
+ if (targetExists) {
640
+ if (dropTarget) {
641
+ await storage.dropCollection(toDb, toColl);
642
+ }
643
+ else {
644
+ return {
645
+ ok: 0,
646
+ errmsg: `target namespace ${to} already exists`,
647
+ code: 48,
648
+ codeName: 'NamespaceExists',
649
+ };
650
+ }
651
+ }
652
+ // Same database rename
653
+ if (fromDb === toDb) {
654
+ await storage.renameCollection(fromDb, fromColl, toColl);
655
+ }
656
+ else {
657
+ // Cross-database rename: copy documents then drop source
658
+ await storage.createCollection(toDb, toColl);
659
+ const docs = await storage.findAll(fromDb, fromColl);
660
+ for (const doc of docs) {
661
+ await storage.insertOne(toDb, toColl, doc);
662
+ }
663
+ await storage.dropCollection(fromDb, fromColl);
664
+ }
665
+ return { ok: 1 };
666
+ }
667
+ }
668
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWRtaW5IYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvdHNtZGIvc2VydmVyL2hhbmRsZXJzL0FkbWluSGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHdCQUF3QixDQUFDO0FBRWxELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU5RDs7R0FFRztBQUNILE1BQU0sT0FBTyxZQUFZO0lBQ3ZCLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBd0I7UUFDbkMsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUU1QixvQ0FBb0M7UUFDcEMsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNsQyxDQUFDO2FBQU0sSUFBSSxPQUFPLENBQUMsYUFBYSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9DLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzNDLENBQUM7YUFBTSxJQUFJLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakQsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0MsQ0FBQzthQUFNLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN0QyxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbEMsQ0FBQzthQUFNLElBQUksT0FBTyxDQUFDLFlBQVksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM5QyxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQyxDQUFDO2FBQU0sSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRSxD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