Skip to content

Commit 43f6629

Browse files
committed
WIP proxy
1 parent 2f9ad4d commit 43f6629

File tree

1 file changed

+90
-59
lines changed

1 file changed

+90
-59
lines changed

src/cmap/command_monitoring_events.ts

Lines changed: 90 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,32 @@ const LEGACY_FIND_QUERY_MAP: { [key: string]: string } = {
236236
$snapshot: 'snapshot'
237237
};
238238

239+
const LEGACY_FIND_QUERY_MAP_rev: Record<any, string> = {
240+
filter: '$query',
241+
sort: '$orderby',
242+
hint: '$hint',
243+
comment: '$comment',
244+
maxScan: '$maxScan',
245+
max: '$max',
246+
min: '$min',
247+
returnKey: '$returnKey',
248+
showRecordId: '$showDiskLoc',
249+
maxTimeMS: '$maxTimeMS',
250+
snapshot: '$snapshot'
251+
};
252+
239253
const LEGACY_FIND_OPTIONS_MAP = {
240254
numberToSkip: 'skip',
241255
numberToReturn: 'batchSize',
242256
returnFieldSelector: 'projection'
243257
} as const;
244258

259+
const LEGACY_FIND_OPTIONS_MAP_rev: Record<any, string> = {
260+
skip: 'numberToSkip',
261+
batchSize: 'numberToReturn',
262+
projection: 'returnFieldSelector'
263+
} as const;
264+
245265
const OP_QUERY_KEYS = [
246266
'tailable',
247267
'oplogReplay',
@@ -254,70 +274,69 @@ const OP_QUERY_KEYS = [
254274
/** Extract the actual command from the query, possibly up-converting if it's a legacy format */
255275
function extractCommand(command: WriteProtocolMessageType): Document {
256276
if (command instanceof OpMsgRequest) {
257-
const cmd = deepCopy(command.command);
258-
// For OP_MSG with payload type 1 we need to pull the documents
259-
// array out of the document sequence for monitoring.
260-
if (cmd.ops instanceof DocumentSequence) {
261-
cmd.ops = cmd.ops.documents;
262-
}
263-
if (cmd.nsInfo instanceof DocumentSequence) {
264-
cmd.nsInfo = cmd.nsInfo.documents;
265-
}
277+
const cmd = new Proxy(command.command, {
278+
// For OP_MSG with payload type 1 we need to pull the documents
279+
// array out of the document sequence for monitoring.
280+
get(target, prop) {
281+
if (prop === 'ops') {
282+
if (target.ops instanceof DocumentSequence) {
283+
return target.ops.documents;
284+
} else {
285+
return target.ops;
286+
}
287+
}
288+
289+
if (prop === 'nsInfo') {
290+
if (target.nsInfo instanceof DocumentSequence) {
291+
return target.nsInfo.documents;
292+
} else {
293+
return target.nsInfo;
294+
}
295+
}
296+
297+
return typeof prop === 'string' && prop in target ? target[prop] : undefined;
298+
}
299+
});
266300
return cmd;
267301
}
268302

269303
if (command.query?.$query) {
270-
let result: Document;
271-
if (command.ns === 'admin.$cmd') {
272-
// up-convert legacy command
273-
result = Object.assign({}, command.query.$query);
274-
} else {
275-
// up-convert legacy find command
276-
result = { find: collectionName(command) };
277-
Object.keys(LEGACY_FIND_QUERY_MAP).forEach(key => {
278-
if (command.query[key] != null) {
279-
result[LEGACY_FIND_QUERY_MAP[key]] = deepCopy(command.query[key]);
304+
const cmd = new Proxy(command, {
305+
get(target: Document, prop) {
306+
if (target.ns === 'admin.$cmd') {
307+
// up-convert legacy command
308+
return target.query.$query[prop];
309+
} else {
310+
// up-convert legacy find command
311+
if (prop === 'find') {
312+
return collectionName(target as OpQueryRequest);
313+
}
314+
if (typeof prop !== 'string') return undefined;
315+
316+
if (LEGACY_FIND_QUERY_MAP_rev[prop] != null) {
317+
return target.query[LEGACY_FIND_QUERY_MAP_rev[prop]];
318+
}
280319
}
281-
});
282-
}
283320

284-
Object.keys(LEGACY_FIND_OPTIONS_MAP).forEach(key => {
285-
const legacyKey = key as keyof typeof LEGACY_FIND_OPTIONS_MAP;
286-
if (command[legacyKey] != null) {
287-
result[LEGACY_FIND_OPTIONS_MAP[legacyKey]] = deepCopy(command[legacyKey]);
288-
}
289-
});
321+
if (LEGACY_FIND_OPTIONS_MAP_rev[prop] != null) {
322+
return target[LEGACY_FIND_OPTIONS_MAP_rev[prop]];
323+
}
290324

291-
OP_QUERY_KEYS.forEach(key => {
292-
if (command[key]) {
293-
result[key] = command[key];
325+
if (prop === 'limit' && target.pre32Limit != null) return target.pre32Limit;
326+
327+
return target[prop];
294328
}
295329
});
296330

297-
if (command.pre32Limit != null) {
298-
result.limit = command.pre32Limit;
299-
}
300-
301-
if (command.query.$explain) {
302-
return { explain: result };
303-
}
304-
return result;
331+
if (command.query.$explain) return { explain: cmd };
332+
return cmd;
305333
}
306334

307-
const clonedQuery: Record<string, unknown> = {};
308-
const clonedCommand: Record<string, unknown> = {};
309335
if (command.query) {
310-
for (const k in command.query) {
311-
clonedQuery[k] = deepCopy(command.query[k]);
312-
}
313-
clonedCommand.query = clonedQuery;
314-
}
315-
316-
for (const k in command) {
317-
if (k === 'query') continue;
318-
clonedCommand[k] = deepCopy((command as unknown as Record<string, unknown>)[k]);
336+
return new Proxy(command.query, {});
337+
} else {
338+
return new Proxy(command, {});
319339
}
320-
return command.query ? clonedQuery : clonedCommand;
321340
}
322341

323342
function extractReply(command: WriteProtocolMessageType, reply?: Document) {
@@ -326,22 +345,34 @@ function extractReply(command: WriteProtocolMessageType, reply?: Document) {
326345
}
327346

328347
if (command instanceof OpMsgRequest) {
329-
return deepCopy(reply.result ? reply.result : reply);
348+
return new Proxy(reply, {});
330349
}
331350

332351
// is this a legacy find command?
333352
if (command.query && command.query.$query != null) {
334-
return {
335-
ok: 1,
336-
cursor: {
337-
id: deepCopy(reply.cursorId),
338-
ns: namespace(command),
339-
firstBatch: deepCopy(reply.documents)
353+
return new Proxy(reply, {
354+
get(target, prop) {
355+
if (typeof prop !== 'string') return undefined;
356+
if (prop === 'ok') {
357+
return 1;
358+
}
359+
if (prop === 'cursor') {
360+
return {
361+
id: target.cursorId,
362+
ns: namespace(command),
363+
firstBatch: target.documents
364+
};
365+
}
366+
return target[prop];
340367
}
341-
};
368+
});
342369
}
343370

344-
return deepCopy(reply.result ? reply.result : reply);
371+
if (reply.result != null) {
372+
return new Proxy(reply.result, {});
373+
} else {
374+
return new Proxy(reply, {});
375+
}
345376
}
346377

347378
function extractConnectionDetails(connection: Connection) {

0 commit comments

Comments
 (0)