import {sysCollNamePrefix} from "jstests/core/timeseries/libs/timeseries_writes_util.js"; /** * Resolves the command name for the given 'cmdObj'. */ export function getCommandName(cmdObj) { return Object.keys(cmdObj)[0]; } /** * Returns the inner command if 'cmdObj' represents an explain command, or simply 'cmdObj' * otherwise. */ export function getInnerCommand(cmdObj) { const isExplain = "explain" in cmdObj; if (!isExplain) { return cmdObj; } if (typeof cmdObj.explain === "object") { return cmdObj.explain; } const {explain, ...cmdWithoutExplain} = cmdObj; return cmdWithoutExplain; } /** * Returns the explain command object for the given 'cmdObj'. */ export function getExplainCommand(cmdObj) { const isAggregateCmd = getCommandName(cmdObj) === "aggregate"; // Extract the 'writeConcern' from the command, as it can not be passed to explain. const {writeConcern, ...cmdWithoutWriteConcern} = cmdObj; return isAggregateCmd ? {explain: {...cmdWithoutWriteConcern, cursor: {}}} : {explain: cmdWithoutWriteConcern}; } /** * Resolves the collection name for the given 'cmdObj'. If the command targets a view, then this * will recursively find the underlying collection's name and return it. Returns 'undefined' if the * collection does not exist. */ export function getCollectionName(db, cmdObj) { try { const collectionsInfo = db.getCollectionInfos(); if (!collectionsInfo || collectionsInfo.length === 0) { return undefined; } let viewOn; let name = cmdObj[getCommandName(cmdObj)]; do { let collInfo = collectionsInfo.find(c => c.name === name); if (!collInfo) { name = undefined; } viewOn = collInfo?.options?.viewOn; if (viewOn) { name = viewOn; } } while (viewOn); return name; } catch (ex) { switch (ex.code) { case ErrorCodes.InvalidViewDefinition: { // The 'DB.prototype.getCollectionInfos()' implementation may throw an exception // when faced with a malformed view definition. This is analogous to a missing // collection for the purpose of passthrough suites. return undefined; } default: throw ex; } } } export function isSystemCollectionName(collectionName) { return collectionName.startsWith("system."); } export function isInternalDbName(dbName) { return ["admin", "local", "config"].includes(dbName); } /** * Returns true iff the 'collectionName' exists and it is a timeseries collection. */ export function isTimeSeriesCollection(db, collectionName) { const collectionInfo = db.getCollectionInfos({name: collectionName}); if (!collectionInfo || collectionInfo.length === 0) { return false; } return collectionInfo[0].type === "timeseries" || collectionName.startsWith("system.bucket."); } /** * Return true iff this is a "system.bucket.*" collection. */ export function isSystemBucketNss(innerCmd) { const nss = innerCmd[getCommandName(innerCmd)]; return typeof nss === "string" && nss.startsWith(sysCollNamePrefix); }