summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Verch <shaun.verch@10gen.com>2013-08-18 11:23:55 -0700
committerShaun Verch <shaun.verch@10gen.com>2013-09-05 13:49:33 -0400
commit43e7502572b4a217eb3f57eee479585ae2a2d19e (patch)
tree7db0ce4aec250b4147ec03842c526a194eda64c0
parent4ffd53218fc9d8ad63e34c7cfec4247da2d1bef7 (diff)
downloadmongo-43e7502572b4a217eb3f57eee479585ae2a2d19e.tar.gz
SERVER-8510 Added legacy interface to Environment and Value to ease transition from variables_map
-rw-r--r--src/mongo/util/options_parser/environment.cpp23
-rw-r--r--src/mongo/util/options_parser/environment.h15
-rw-r--r--src/mongo/util/options_parser/options_parser.cpp14
-rw-r--r--src/mongo/util/options_parser/options_parser_test.cpp71
-rw-r--r--src/mongo/util/options_parser/value.cpp14
-rw-r--r--src/mongo/util/options_parser/value.h32
6 files changed, 163 insertions, 6 deletions
diff --git a/src/mongo/util/options_parser/environment.cpp b/src/mongo/util/options_parser/environment.cpp
index 0db43abef4a..78524b7e408 100644
--- a/src/mongo/util/options_parser/environment.cpp
+++ b/src/mongo/util/options_parser/environment.cpp
@@ -135,6 +135,29 @@ namespace optionenvironment {
return Status::OK();
}
+ /** Implementation of legacy interface to be consistent with
+ * boost::program_options::variables_map during the transition period
+ *
+ * boost::program_options::variables_map inherits the count function from std::map, which
+ * returns 1 if the value is set, and 0 if it is not set
+ */
+ bool Environment::count(const Key& key) const {
+ Value value;
+ Status ret = get(key, &value);
+ if (ret.isOK()) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ Value Environment::operator[](const Key& key) const {
+ Value value;
+ Status ret = get(key, &value);
+ return value;
+ }
+
/* Debugging */
void Environment::dump() {
std::map<Key, Value>::iterator iter;
diff --git a/src/mongo/util/options_parser/environment.h b/src/mongo/util/options_parser/environment.h
index 15725d08814..c31c5ed0bfe 100644
--- a/src/mongo/util/options_parser/environment.h
+++ b/src/mongo/util/options_parser/environment.h
@@ -139,6 +139,21 @@ namespace optionenvironment {
*/
Status setAll(const Environment& other);
+ /** The functions below are the legacy interface to be consistent with
+ * boost::program_options::variables_map during the transition period
+ */
+
+ /**
+ * @return 1 if the given Key has a Value set in this Environment and 0 if not
+ */
+ bool count(const Key& key) const;
+
+ /**
+ * @return the Value for the given Key in this Environment. Returns an empty Value if
+ * Key is not set.
+ */
+ Value operator[](const Key& key) const;
+
/* Debugging */
void dump();
diff --git a/src/mongo/util/options_parser/options_parser.cpp b/src/mongo/util/options_parser/options_parser.cpp
index f4de3e2c2ff..37c8a1f1568 100644
--- a/src/mongo/util/options_parser/options_parser.cpp
+++ b/src/mongo/util/options_parser/options_parser.cpp
@@ -122,6 +122,20 @@ namespace optionenvironment {
if (!ret.isOK()) {
return ret;
}
+
+ // XXX: Don't set switches that are false, to maintain backwards compatibility
+ // with the old behavior during the transition to the new parser
+ if (iterator->_type == Switch) {
+ bool value;
+ ret = optionValue.get(&value);
+ if (!ret.isOK()) {
+ return ret;
+ }
+ if (!value) {
+ continue;
+ }
+ }
+
environment->set(iterator->_dottedName, optionValue);
}
}
diff --git a/src/mongo/util/options_parser/options_parser_test.cpp b/src/mongo/util/options_parser/options_parser_test.cpp
index 21f675189ea..1491edcc4d9 100644
--- a/src/mongo/util/options_parser/options_parser_test.cpp
+++ b/src/mongo/util/options_parser/options_parser_test.cpp
@@ -589,12 +589,7 @@ namespace {
ASSERT_EQUALS(verbose, true);
}
else {
- // TODO: Figure out if these are the semantics we want for switches. Right now they
- // will always set a boolean value in the environment even if they aren't present.
- ASSERT_OK(environment.get(moe::Key(s), &value));
- bool verbose;
- ASSERT_OK(value.get(&verbose));
- ASSERT_EQUALS(verbose, false);
+ ASSERT_NOT_OK(environment.get(moe::Key(s), &value));
}
}
}
@@ -1199,4 +1194,68 @@ namespace {
ASSERT_EQUALS(*setParameterit, "val4");
}
+ TEST(LegacyInterface, Good) {
+ moe::OptionsParser parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--port");
+ argv.push_back("5");
+ std::map<std::string, std::string> env_map;
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_TRUE(environment.count("port"));
+ int port;
+ try {
+ port = environment["port"].as<int>();
+ }
+ catch ( std::exception &e ) {
+ FAIL(e.what());
+ }
+ ASSERT_EQUALS(port, 5);
+ }
+
+ TEST(LegacyInterface, NotSpecified) {
+ moe::OptionsParser parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ std::map<std::string, std::string> env_map;
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_FALSE(environment.count("port"));
+ }
+
+ TEST(LegacyInterface, BadType) {
+ moe::OptionsParser parser;
+ moe::Environment environment;
+
+ moe::OptionSection testOpts;
+ testOpts.addOption(moe::OptionDescription("port", "port", moe::Int, "Port"));
+
+ std::vector<std::string> argv;
+ argv.push_back("binaryname");
+ argv.push_back("--port");
+ argv.push_back("5");
+ std::map<std::string, std::string> env_map;
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_TRUE(environment.count("port"));
+ std::string port;
+ try {
+ port = environment["port"].as<std::string>();
+ FAIL("Expected exception trying to convert int to type string");
+ }
+ catch ( std::exception &e ) {
+ }
+ }
+
} // unnamed namespace
diff --git a/src/mongo/util/options_parser/value.cpp b/src/mongo/util/options_parser/value.cpp
index a4c46954e6b..6b83b5180cf 100644
--- a/src/mongo/util/options_parser/value.cpp
+++ b/src/mongo/util/options_parser/value.cpp
@@ -177,6 +177,20 @@ namespace optionenvironment {
}
return sb.str();
}
+ const std::type_info& Value::type() const {
+ switch (_type) {
+ case StringVector: return typeid(std::vector<std::string>);
+ case Bool: return typeid(bool);
+ case Double: return typeid(double);
+ case Int: return typeid(int);
+ case Long: return typeid(long);
+ case String: return typeid(std::string);
+ case UnsignedLongLong: return typeid(unsigned long long);
+ case Unsigned: return typeid(unsigned);
+ case None: return typeid(void);
+ default: return typeid(void);
+ }
+ }
} // namespace optionenvironment
} // namespace mongo
diff --git a/src/mongo/util/options_parser/value.h b/src/mongo/util/options_parser/value.h
index 3d50cc7a445..f75d7d06895 100644
--- a/src/mongo/util/options_parser/value.h
+++ b/src/mongo/util/options_parser/value.h
@@ -18,6 +18,7 @@
#include <vector>
#include "mongo/base/status.h"
+#include "mongo/bson/util/builder.h"
namespace mongo {
namespace optionenvironment {
@@ -94,6 +95,23 @@ namespace optionenvironment {
*/
std::string toString() const;
+ /**
+ * The functions below are the legacy interface to be consistent with boost::any during the
+ * transition period
+ */
+
+ /**
+ * Returns the contents of this Value as type T. Throws MsgAssertionException if the type
+ * does not match
+ */
+ template <typename T>
+ T as() const;
+
+ /**
+ * Return the type_info for this value
+ */
+ const std::type_info& type() const;
+
private:
std::vector<std::string> _stringVectorVal;
std::string _stringVal;
@@ -122,5 +140,19 @@ namespace optionenvironment {
Type _type;
};
+ template <typename T>
+ T Value::as() const {
+ T valueType;
+
+ Status ret = get(&valueType);
+ if (!ret.isOK()) {
+ StringBuilder message;
+ message << "failed to extract typed value from Value container: " << ret.toString();
+ throw MsgAssertionException(17114, message.str());
+ }
+
+ return valueType;
+ }
+
} // namespace optionenvironment
} // namespace mongo