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