summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2022-12-15 11:21:38 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-12-20 16:07:41 +0000
commit877cf79d2dfce0679703dd6c7d561e97dbab362a (patch)
tree0d6c8f79c8a80cc3e4c19675a5352c787345be7d
parent4dccf13844ceb965fd9c141758d81f5618693c30 (diff)
downloadmongo-877cf79d2dfce0679703dd6c7d561e97dbab362a.tar.gz
SERVER-71967: Add a `writeBsonArrayToFile` shell method.
-rw-r--r--src/mongo/shell/shell_utils_extended.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/mongo/shell/shell_utils_extended.cpp b/src/mongo/shell/shell_utils_extended.cpp
index 373dc6bb460..2cf5e971501 100644
--- a/src/mongo/shell/shell_utils_extended.cpp
+++ b/src/mongo/shell/shell_utils_extended.cpp
@@ -407,6 +407,51 @@ BSONObj writeFile(const BSONObj& args, void* data) {
return undefinedReturn;
}
+/**
+ * Writes an array of bson objects one after another. The format is readable by the `bsondump` tool.
+ */
+BSONObj writeBsonArrayToFile(const BSONObj& args, void* data) {
+ uassert(7196709, "writeBsonArrayToFile needs 2 arguments", args.nFields() == 2);
+
+ BSONObjIterator it(args);
+ auto filePathElem = it.next();
+ uassert(7196708, "first argument must be a string", filePathElem.type() == BSONType::String);
+
+ auto fileContentElem = it.next();
+ uassert(
+ 7196707, "second argument must be a BSON array", fileContentElem.type() == BSONType::Array);
+
+ const boost::filesystem::path originalFilePath{filePathElem.String()};
+ const boost::filesystem::path normalizedFilePath{originalFilePath.lexically_normal()};
+ const boost::filesystem::path absoluteFilePath{boost::filesystem::absolute(normalizedFilePath)};
+
+ uassert(7196706,
+ "bsonArrayToFile() can only write a file in a directory which already exists",
+ boost::filesystem::exists(absoluteFilePath.parent_path()));
+ uassert(7196705,
+ "bsonArrayToFile() can only write to a file which does not yet exist",
+ !boost::filesystem::exists(absoluteFilePath));
+ uassert(7196704,
+ "the file name must be compatible with POSIX and Windows",
+ boost::filesystem::portable_name(absoluteFilePath.filename().string()));
+
+ std::ios::openmode mode = std::ios::out | std::ios::binary;
+ boost::filesystem::ofstream ofs{absoluteFilePath, mode};
+ uassert(7196703,
+ str::stream() << "failed to open file " << normalizedFilePath.string()
+ << " for writing",
+ ofs);
+
+ for (const auto& obj : fileContentElem.Obj()) {
+ ofs.write(obj.Obj().objdata(), obj.objsize());
+ uassert(7196702, "Error writing to file", !ofs.bad());
+ }
+ ofs.flush();
+ uassert(7196701, str::stream() << "failed to write to file " << absoluteFilePath.string(), ofs);
+
+ return undefinedReturn;
+}
+
BSONObj getHostName(const BSONObj& a, void* data) {
uassert(13411, "getHostName accepts no arguments", a.nFields() == 0);
char buf[260]; // HOST_NAME_MAX is usually 255
@@ -578,6 +623,7 @@ void installShellUtilsExtended(Scope& scope) {
scope.injectNative("_copyFileRange", copyFileRange);
scope.injectNative("_readDumpFile", readDumpFile);
scope.injectNative("_getEnv", shellGetEnv);
+ scope.injectNative("writeBsonArrayToFile", writeBsonArrayToFile);
}
} // namespace shell_utils