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