diff options
author | Shaun Verch <shaun.verch@10gen.com> | 2013-08-18 11:23:55 -0700 |
---|---|---|
committer | Shaun Verch <shaun.verch@10gen.com> | 2013-09-05 13:49:33 -0400 |
commit | 43e7502572b4a217eb3f57eee479585ae2a2d19e (patch) | |
tree | 7db0ce4aec250b4147ec03842c526a194eda64c0 | |
parent | 4ffd53218fc9d8ad63e34c7cfec4247da2d1bef7 (diff) | |
download | mongo-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.cpp | 23 | ||||
-rw-r--r-- | src/mongo/util/options_parser/environment.h | 15 | ||||
-rw-r--r-- | src/mongo/util/options_parser/options_parser.cpp | 14 | ||||
-rw-r--r-- | src/mongo/util/options_parser/options_parser_test.cpp | 71 | ||||
-rw-r--r-- | src/mongo/util/options_parser/value.cpp | 14 | ||||
-rw-r--r-- | src/mongo/util/options_parser/value.h | 32 |
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 |