diff options
author | Geert Bosch <geert@mongodb.com> | 2017-05-12 18:38:22 -0400 |
---|---|---|
committer | Geert Bosch <geert@mongodb.com> | 2017-06-09 16:50:41 -0400 |
commit | 6fe725018db0d9a8e580faabe762bb5a153f4ae8 (patch) | |
tree | 8e117673254a45cbcefbe15637e2c7340737d876 /src/mongo/scripting/mozjs | |
parent | 1b8c7d24d7a44c1b6784705c9770768743c71943 (diff) | |
download | mongo-6fe725018db0d9a8e580faabe762bb5a153f4ae8.tar.gz |
SERVER-29154 Have mongo shell display and accept UUID as such instead of BinData(4, ...)
Diffstat (limited to 'src/mongo/scripting/mozjs')
-rw-r--r-- | src/mongo/scripting/mozjs/bindata.cpp | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/src/mongo/scripting/mozjs/bindata.cpp b/src/mongo/scripting/mozjs/bindata.cpp index d528f6b1651..6d91dea8008 100644 --- a/src/mongo/scripting/mozjs/bindata.cpp +++ b/src/mongo/scripting/mozjs/bindata.cpp @@ -33,6 +33,7 @@ #include <cctype> #include <iomanip> +#include "mongo/bson/bsonobjbuilder.h" #include "mongo/scripting/mozjs/implscope.h" #include "mongo/scripting/mozjs/internedstring.h" #include "mongo/scripting/mozjs/objectwrapper.h" @@ -42,6 +43,7 @@ #include "mongo/util/base64.h" #include "mongo/util/hex.h" #include "mongo/util/mongoutils/str.h" +#include "mongo/util/uuid.h" namespace mongo { namespace mozjs { @@ -114,16 +116,30 @@ void BinDataInfo::finalize(JSFreeOp* fop, JSObject* obj) { } void BinDataInfo::Functions::UUID::call(JSContext* cx, JS::CallArgs args) { - if (args.length() != 1) - uasserted(ErrorCodes::BadValue, "UUID needs 1 argument"); - - auto arg = args.get(0); - auto str = ValueWriter(cx, arg).toString(); - - if (str.length() != 32) - uasserted(ErrorCodes::BadValue, "UUID string must have 32 characters"); - - hexToBinData(cx, bdtUUID, arg, args.rval()); + boost::optional<mongo::UUID> uuid; + + if (args.length() == 0) { + uuid = mongo::UUID::gen(); + } else { + uassert(ErrorCodes::BadValue, "UUID needs 0 or 1 arguments", args.length() == 1); + auto arg = args.get(0); + std::string str = ValueWriter(cx, arg).toString(); + + // For backward compatibility quietly accept and convert 32-character hex strings to + // BinData(3, ...) as used for the deprecated UUID v3 BSON type. + if (str.length() == 32) { + hexToBinData(cx, bdtUUID, arg, args.rval()); + return; + } + uuid = uassertStatusOK(mongo::UUID::parse(str)); + }; + ConstDataRange cdr = uuid->toCDR(); + std::string encoded = mongo::base64::encode(cdr.data(), cdr.length()); + + JS::AutoValueArray<2> newArgs(cx); + newArgs[0].setInt32(newUUID); + ValueReader(cx, newArgs[1]).fromStringData(encoded); + getScope(cx)->getProto<BinDataInfo>().newInstance(newArgs, args.rval()); } void BinDataInfo::Functions::MD5::call(JSContext* cx, JS::CallArgs args) { @@ -158,9 +174,21 @@ void BinDataInfo::Functions::toString::call(JSContext* cx, JS::CallArgs args) { auto str = getEncoded(args.thisv()); str::stream ss; + auto binType = o.getNumber(InternedString::type); + + if (binType == newUUID) { + auto decoded = mongo::base64::decode(*str); + + // If this is in fact a UUID, use a more friendly string representation. + if (decoded.length() == mongo::UUID::kNumBytes) { + mongo::UUID uuid = mongo::UUID::fromCDR({decoded.data(), decoded.length()}); + ss << "UUID(\"" << uuid.toString() << "\")"; + ValueReader(cx, args.rval()).fromStringData(ss.operator std::string()); + return; + } + } - ss << "BinData(" << o.getNumber(InternedString::type) << ",\"" << *str << "\")"; - + ss << "BinData(" << binType << ",\"" << *str << "\")"; ValueReader(cx, args.rval()).fromStringData(ss.operator std::string()); } |