You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.3 KiB
83 lines
2.3 KiB
import { Code, Document } from '../bson';
|
|
import type { Collection } from '../collection';
|
|
import type { Db } from '../db';
|
|
import { MongoServerError } from '../error';
|
|
import { ReadPreference } from '../read_preference';
|
|
import type { Server } from '../sdam/server';
|
|
import type { ClientSession } from '../sessions';
|
|
import type { Callback } from '../utils';
|
|
import { CommandOperation, CommandOperationOptions } from './command';
|
|
|
|
/** @public */
|
|
export interface EvalOptions extends CommandOperationOptions {
|
|
nolock?: boolean;
|
|
}
|
|
|
|
/** @internal */
|
|
export class EvalOperation extends CommandOperation<Document> {
|
|
override options: EvalOptions;
|
|
code: Code;
|
|
parameters?: Document | Document[];
|
|
|
|
constructor(
|
|
db: Db | Collection,
|
|
code: Code,
|
|
parameters?: Document | Document[],
|
|
options?: EvalOptions
|
|
) {
|
|
super(db, options);
|
|
|
|
this.options = options ?? {};
|
|
this.code = code;
|
|
this.parameters = parameters;
|
|
// force primary read preference
|
|
Object.defineProperty(this, 'readPreference', {
|
|
value: ReadPreference.primary,
|
|
configurable: false,
|
|
writable: false
|
|
});
|
|
}
|
|
|
|
override execute(
|
|
server: Server,
|
|
session: ClientSession | undefined,
|
|
callback: Callback<Document>
|
|
): void {
|
|
let finalCode = this.code;
|
|
let finalParameters: Document[] = [];
|
|
|
|
// If not a code object translate to one
|
|
if (!(finalCode && (finalCode as unknown as { _bsontype: string })._bsontype === 'Code')) {
|
|
finalCode = new Code(finalCode as never);
|
|
}
|
|
|
|
// Ensure the parameters are correct
|
|
if (this.parameters != null && typeof this.parameters !== 'function') {
|
|
finalParameters = Array.isArray(this.parameters) ? this.parameters : [this.parameters];
|
|
}
|
|
|
|
// Create execution selector
|
|
const cmd: Document = { $eval: finalCode, args: finalParameters };
|
|
|
|
// Check if the nolock parameter is passed in
|
|
if (this.options.nolock) {
|
|
cmd.nolock = this.options.nolock;
|
|
}
|
|
|
|
// Execute the command
|
|
super.executeCommand(server, session, cmd, (err, result) => {
|
|
if (err) return callback(err);
|
|
if (result && result.ok === 1) {
|
|
return callback(undefined, result.retval);
|
|
}
|
|
|
|
if (result) {
|
|
callback(new MongoServerError({ message: `eval failed: ${result.errmsg}` }));
|
|
return;
|
|
}
|
|
|
|
callback(err, result);
|
|
});
|
|
}
|
|
}
|