summaryrefslogtreecommitdiff
path: root/src/mongo/scripting/mozjs
diff options
context:
space:
mode:
authorMatt Cotter <matt.cotter@mongodb.com>2016-07-13 14:39:35 -0400
committerMatt Cotter <matt.cotter@mongodb.com>2016-08-18 14:13:01 -0400
commit88b540f0c14c7ab8af708aecc4cd6df83081b32e (patch)
treea6f01563ac2b8db7d34f98e5fab3d17f5416e315 /src/mongo/scripting/mozjs
parentceeb17e4265c4c48765acbf9ad6a60b5f1889332 (diff)
downloadmongo-88b540f0c14c7ab8af708aecc4cd6df83081b32e.tar.gz
SERVER-22382 allow mongo --host to take uri
Diffstat (limited to 'src/mongo/scripting/mozjs')
-rw-r--r--src/mongo/scripting/mozjs/implscope.cpp10
-rw-r--r--src/mongo/scripting/mozjs/implscope.h13
-rw-r--r--src/mongo/scripting/mozjs/internedstring.defs8
-rw-r--r--src/mongo/scripting/mozjs/mongo.cpp8
-rw-r--r--src/mongo/scripting/mozjs/objectwrapper.cpp7
-rw-r--r--src/mongo/scripting/mozjs/objectwrapper.h1
-rw-r--r--src/mongo/scripting/mozjs/uri.cpp105
-rw-r--r--src/mongo/scripting/mozjs/uri.h52
-rw-r--r--src/mongo/scripting/mozjs/valuereader.cpp34
-rw-r--r--src/mongo/scripting/mozjs/valuereader.h1
10 files changed, 213 insertions, 26 deletions
diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp
index 2b01e99454b..fff5f233ac2 100644
--- a/src/mongo/scripting/mozjs/implscope.cpp
+++ b/src/mongo/scripting/mozjs/implscope.cpp
@@ -336,12 +336,12 @@ MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine)
_bsonProto(_context),
_codeProto(_context),
_countDownLatchProto(_context),
- _cursorProto(_context),
_cursorHandleProto(_context),
+ _cursorProto(_context),
_dbCollectionProto(_context),
+ _dbProto(_context),
_dbPointerProto(_context),
_dbQueryProto(_context),
- _dbProto(_context),
_dbRefProto(_context),
_errorProto(_context),
_jsThreadProto(_context),
@@ -351,13 +351,14 @@ MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine)
_mongoHelpersProto(_context),
_mongoLocalProto(_context),
_nativeFunctionProto(_context),
+ _numberDecimalProto(_context),
_numberIntProto(_context),
_numberLongProto(_context),
- _numberDecimalProto(_context),
_objectProto(_context),
_oidProto(_context),
_regExpProto(_context),
- _timestampProto(_context) {
+ _timestampProto(_context),
+ _uriProto(_context) {
kCurrentScope = this;
// The default is quite low and doesn't seem to directly correlate with
@@ -790,6 +791,7 @@ void MozJSImplScope::installBSONTypes() {
_oidProto.install(_global);
_regExpProto.install(_global);
_timestampProto.install(_global);
+ _uriProto.install(_global);
// This builtin map is a javascript 6 thing. We want our version. so
// take theirs out
diff --git a/src/mongo/scripting/mozjs/implscope.h b/src/mongo/scripting/mozjs/implscope.h
index d8225bffdde..080716428ac 100644
--- a/src/mongo/scripting/mozjs/implscope.h
+++ b/src/mongo/scripting/mozjs/implscope.h
@@ -60,6 +60,7 @@
#include "mongo/scripting/mozjs/oid.h"
#include "mongo/scripting/mozjs/regexp.h"
#include "mongo/scripting/mozjs/timestamp.h"
+#include "mongo/scripting/mozjs/uri.h"
namespace mongo {
namespace mozjs {
@@ -289,6 +290,11 @@ public:
return _timestampProto;
}
+ template <typename T>
+ typename std::enable_if<std::is_same<T, URIInfo>::value, WrapType<T>&>::type getProto() {
+ return _uriProto;
+ }
+
void setQuickExit(int exitCode);
bool getQuickExit(int* exitCode);
@@ -380,12 +386,12 @@ private:
WrapType<BSONInfo> _bsonProto;
WrapType<CodeInfo> _codeProto;
WrapType<CountDownLatchInfo> _countDownLatchProto;
- WrapType<CursorInfo> _cursorProto;
WrapType<CursorHandleInfo> _cursorHandleProto;
+ WrapType<CursorInfo> _cursorProto;
WrapType<DBCollectionInfo> _dbCollectionProto;
+ WrapType<DBInfo> _dbProto;
WrapType<DBPointerInfo> _dbPointerProto;
WrapType<DBQueryInfo> _dbQueryProto;
- WrapType<DBInfo> _dbProto;
WrapType<DBRefInfo> _dbRefProto;
WrapType<ErrorInfo> _errorProto;
WrapType<JSThreadInfo> _jsThreadProto;
@@ -395,13 +401,14 @@ private:
WrapType<MongoHelpersInfo> _mongoHelpersProto;
WrapType<MongoLocalInfo> _mongoLocalProto;
WrapType<NativeFunctionInfo> _nativeFunctionProto;
+ WrapType<NumberDecimalInfo> _numberDecimalProto;
WrapType<NumberIntInfo> _numberIntProto;
WrapType<NumberLongInfo> _numberLongProto;
- WrapType<NumberDecimalInfo> _numberDecimalProto;
WrapType<ObjectInfo> _objectProto;
WrapType<OIDInfo> _oidProto;
WrapType<RegExpInfo> _regExpProto;
WrapType<TimestampInfo> _timestampProto;
+ WrapType<URIInfo> _uriProto;
};
inline MozJSImplScope* getScope(JSContext* cx) {
diff --git a/src/mongo/scripting/mozjs/internedstring.defs b/src/mongo/scripting/mozjs/internedstring.defs
index 792ec0bbcb5..fe2394edb27 100644
--- a/src/mongo/scripting/mozjs/internedstring.defs
+++ b/src/mongo/scripting/mozjs/internedstring.defs
@@ -53,3 +53,11 @@ MONGO_MOZJS_INTERNED_STRING(str, "str")
MONGO_MOZJS_INTERNED_STRING(top, "top")
MONGO_MOZJS_INTERNED_STRING(t, "t")
MONGO_MOZJS_INTERNED_STRING(type, "type")
+MONGO_MOZJS_INTERNED_STRING(uri, "uri")
+MONGO_MOZJS_INTERNED_STRING(user, "user")
+MONGO_MOZJS_INTERNED_STRING(password, "password")
+MONGO_MOZJS_INTERNED_STRING(options, "options")
+MONGO_MOZJS_INTERNED_STRING(database, "database")
+MONGO_MOZJS_INTERNED_STRING(isValid, "isValid")
+MONGO_MOZJS_INTERNED_STRING(setName, "setName")
+MONGO_MOZJS_INTERNED_STRING(servers, "servers")
diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp
index b7d9677fd0a..da62b092f34 100644
--- a/src/mongo/scripting/mozjs/mongo.cpp
+++ b/src/mongo/scripting/mozjs/mongo.cpp
@@ -638,8 +638,7 @@ void MongoExternalInfo::construct(JSContext* cx, JS::CallArgs args) {
}
auto statusWithHost = MongoURI::parse(host);
- uassertStatusOK(statusWithHost);
- auto cs = statusWithHost.getValue();
+ auto cs = uassertStatusOK(statusWithHost);
std::string errmsg;
std::unique_ptr<DBClientBase> conn(cs.connect("MongoDB Shell", errmsg));
@@ -657,8 +656,9 @@ void MongoExternalInfo::construct(JSContext* cx, JS::CallArgs args) {
JS_SetPrivate(thisv, new std::shared_ptr<DBClientBase>(conn.release()));
o.setBoolean(InternedString::slaveOk, false);
- o.setString(InternedString::host, host);
- o.setString(InternedString::defaultDB, cs.getDatabase());
+ o.setString(InternedString::host, cs.toString());
+ auto defaultDB = cs.getDatabase() == "" ? "test" : cs.getDatabase();
+ o.setString(InternedString::defaultDB, defaultDB);
args.rval().setObjectOrNull(thisv);
}
diff --git a/src/mongo/scripting/mozjs/objectwrapper.cpp b/src/mongo/scripting/mozjs/objectwrapper.cpp
index 5c921c1ebec..98f8094dfcc 100644
--- a/src/mongo/scripting/mozjs/objectwrapper.cpp
+++ b/src/mongo/scripting/mozjs/objectwrapper.cpp
@@ -361,6 +361,13 @@ void ObjectWrapper::setBSON(Key key, const BSONObj& obj, bool readOnly) {
setValue(key, value);
}
+void ObjectWrapper::setBSONArray(Key key, const BSONObj& obj, bool readOnly) {
+ JS::RootedValue value(_context);
+ ValueReader(_context, &value).fromBSONArray(obj, nullptr, readOnly);
+
+ setValue(key, value);
+}
+
void ObjectWrapper::setValue(Key key, JS::HandleValue val) {
key.set(_context, _object, val);
}
diff --git a/src/mongo/scripting/mozjs/objectwrapper.h b/src/mongo/scripting/mozjs/objectwrapper.h
index 8c85a5b42d1..cf6c61d39e1 100644
--- a/src/mongo/scripting/mozjs/objectwrapper.h
+++ b/src/mongo/scripting/mozjs/objectwrapper.h
@@ -115,6 +115,7 @@ public:
void setBoolean(Key key, bool val);
void setBSONElement(Key key, const BSONElement& elem, const BSONObj& obj, bool readOnly);
void setBSON(Key key, const BSONObj& obj, bool readOnly);
+ void setBSONArray(Key key, const BSONObj& obj, bool readOnly);
void setValue(Key key, JS::HandleValue value);
void setObject(Key key, JS::HandleObject value);
diff --git a/src/mongo/scripting/mozjs/uri.cpp b/src/mongo/scripting/mozjs/uri.cpp
new file mode 100644
index 00000000000..f943bb8a171
--- /dev/null
+++ b/src/mongo/scripting/mozjs/uri.cpp
@@ -0,0 +1,105 @@
+/**
+ * Copyright (C) 2016 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects
+ * for all of the code used other than as permitted herein. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version. If you
+ * delete this exception statement from all source files in the program,
+ * then also delete it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/scripting/mozjs/uri.h"
+
+#include <algorithm>
+#include <iterator>
+
+#include "mongo/client/mongo_uri.h"
+#include "mongo/scripting/mozjs/implscope.h"
+#include "mongo/scripting/mozjs/objectwrapper.h"
+#include "mongo/scripting/mozjs/valuereader.h"
+#include "mongo/scripting/mozjs/valuewriter.h"
+#include "mongo/scripting/mozjs/wrapconstrainedmethod.h"
+#include "mongo/stdx/memory.h"
+#include "mongo/util/mongoutils/str.h"
+
+namespace mongo {
+namespace mozjs {
+
+const JSFunctionSpec URIInfo::methods[2] = {
+ MONGO_ATTACH_JS_CONSTRAINED_METHOD(toString, URIInfo), JS_FS_END,
+};
+
+const char* const URIInfo::className = "MongoURI";
+
+void URIInfo::Functions::toString::call(JSContext* cx, JS::CallArgs args) {
+ ObjectWrapper o(cx, args.thisv());
+ ValueReader(cx, args.rval()).fromStringData(o.getString(InternedString::uri));
+}
+
+void URIInfo::construct(JSContext* cx, JS::CallArgs args) {
+ uassert(ErrorCodes::BadValue, "MongoURI needs 1 argument", args.length() == 1);
+
+ JS::HandleValue uriArg = args.get(0);
+ if (!uriArg.isString())
+ uasserted(ErrorCodes::BadValue, "uri must be a string");
+
+ std::string uri = ValueWriter(cx, args.get(0)).toString();
+
+ auto sw = MongoURI::parse(uri);
+ auto parsed = uassertStatusOK(sw);
+
+ BSONArrayBuilder serversBuilder;
+ for (const auto hp : parsed.getServers()) {
+ BSONObjBuilder b;
+ b.append("server", hp.toString());
+ b.append("host", hp.host());
+ if (hp.hasPort()) {
+ b.append("port", hp.port());
+ }
+ serversBuilder.append(b.obj());
+ }
+
+ BSONObjBuilder optsBuilder;
+ for (const auto& kvpair : parsed.getOptions()) {
+ optsBuilder.append(kvpair.first, kvpair.second);
+ }
+
+ JS::RootedObject thisv(cx);
+ auto scope = getScope(cx);
+ scope->getProto<URIInfo>().newObject(&thisv);
+ ObjectWrapper o(cx, thisv);
+
+ o.setValue(InternedString::uri, uriArg);
+ o.setString(InternedString::user, parsed.getUser());
+ o.setString(InternedString::password, parsed.getPassword());
+ o.setBSON(InternedString::options, optsBuilder.obj(), true);
+ o.setString(InternedString::database, parsed.getDatabase());
+ o.setBoolean(InternedString::isValid, parsed.isValid());
+ o.setString(InternedString::setName, parsed.getSetName());
+ o.setBSONArray(InternedString::servers, serversBuilder.arr(), true);
+
+ args.rval().setObjectOrNull(thisv);
+}
+
+} // namespace mozjs
+} // namespace mongo
diff --git a/src/mongo/scripting/mozjs/uri.h b/src/mongo/scripting/mozjs/uri.h
new file mode 100644
index 00000000000..d1b487ce2ab
--- /dev/null
+++ b/src/mongo/scripting/mozjs/uri.h
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2016 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects
+ * for all of the code used other than as permitted herein. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version. If you
+ * delete this exception statement from all source files in the program,
+ * then also delete it in the license file.
+ */
+
+#pragma once
+
+#include "mongo/scripting/mozjs/wraptype.h"
+
+namespace mongo {
+namespace mozjs {
+
+/**
+ * A MongoURI object.
+ */
+struct URIInfo : public BaseInfo {
+ static void construct(JSContext* cx, JS::CallArgs args);
+
+ struct Functions {
+ MONGO_DECLARE_JS_FUNCTION(toString);
+ };
+
+ static const JSFunctionSpec methods[2];
+
+ static const char* const className;
+};
+
+} // namespace mozjs
+} // namespace mongo
diff --git a/src/mongo/scripting/mozjs/valuereader.cpp b/src/mongo/scripting/mozjs/valuereader.cpp
index af26238763d..1eedef58e86 100644
--- a/src/mongo/scripting/mozjs/valuereader.cpp
+++ b/src/mongo/scripting/mozjs/valuereader.cpp
@@ -97,21 +97,7 @@ void ValueReader::fromBSONElement(const BSONElement& elem, const BSONObj& parent
_value.setInt32(elem.Int());
return;
case mongo::Array: {
- JS::AutoValueVector avv(_context);
-
- BSONForEach(subElem, elem.embeddedObject()) {
- JS::RootedValue member(_context);
-
- ValueReader(_context, &member).fromBSONElement(subElem, parent, readOnly);
- if (!avv.append(member)) {
- uasserted(ErrorCodes::JSInterpreterFailure, "Failed to append to JS array");
- }
- }
- JS::RootedObject array(_context, JS_NewArrayObject(_context, avv));
- if (!array) {
- uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_NewArrayObject");
- }
- _value.setObjectOrNull(array);
+ fromBSONArray(elem.embeddedObject(), &parent, readOnly);
return;
}
case mongo::Object:
@@ -254,6 +240,24 @@ void ValueReader::fromBSON(const BSONObj& obj, const BSONObj* parent, bool readO
_value.setObjectOrNull(child);
}
+void ValueReader::fromBSONArray(const BSONObj& obj, const BSONObj* parent, bool readOnly) {
+ JS::AutoValueVector avv(_context);
+
+ BSONForEach(elem, obj) {
+ JS::RootedValue member(_context);
+
+ ValueReader(_context, &member).fromBSONElement(elem, parent ? *parent : obj, readOnly);
+ if (!avv.append(member)) {
+ uasserted(ErrorCodes::JSInterpreterFailure, "Failed to append to JS array");
+ }
+ }
+ JS::RootedObject array(_context, JS_NewArrayObject(_context, avv));
+ if (!array) {
+ uasserted(ErrorCodes::JSInterpreterFailure, "Failed to JS_NewArrayObject");
+ }
+ _value.setObjectOrNull(array);
+}
+
/**
* SpiderMonkey doesn't have a direct entry point to create a jsstring from
* utf8, so we have to flow through some slightly less public interfaces.
diff --git a/src/mongo/scripting/mozjs/valuereader.h b/src/mongo/scripting/mozjs/valuereader.h
index 6b03d30086c..58abed86c45 100644
--- a/src/mongo/scripting/mozjs/valuereader.h
+++ b/src/mongo/scripting/mozjs/valuereader.h
@@ -49,6 +49,7 @@ public:
void fromBSONElement(const BSONElement& elem, const BSONObj& parent, bool readOnly);
void fromBSON(const BSONObj& obj, const BSONObj* parent, bool readOnly);
+ void fromBSONArray(const BSONObj& obj, const BSONObj* parent, bool readOnly);
void fromDouble(double d);
void fromStringData(StringData sd);
void fromDecimal128(Decimal128 decimal);