From 52e6404e0f72b6f994a442084415f518f9ec9f6c Mon Sep 17 00:00:00 2001 From: Zhongyi Xie Date: Mon, 25 Mar 2019 13:19:25 -0700 Subject: [PATCH] ldb command parsing: allow option values to contain equals signs (#5088) Summary: Right now ldb command doesn't allow cases where option values contain equals sign. For example, ``` ldb --db=/tmp/test scan --from='q=3' --max_keys=1 ``` after parsing, ldb will have one option 'db', 'max_keys' and one flag 'from'. This PR updates the parsing logic so that it now supports the above mentioned cases Pull Request resolved: https://github.com/facebook/rocksdb/pull/5088 Differential Revision: D14600869 Pulled By: miasantreble fbshipit-source-id: c6ef518c74a98d7b6675ea5954ae08b1bda5554e --- include/rocksdb/utilities/ldb_cmd.h | 6 +++++ tools/ldb_cmd.cc | 9 ++++++- tools/ldb_cmd_test.cc | 37 +++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/include/rocksdb/utilities/ldb_cmd.h b/include/rocksdb/utilities/ldb_cmd.h index 907c9daf2..57ab88a34 100644 --- a/include/rocksdb/utilities/ldb_cmd.h +++ b/include/rocksdb/utilities/ldb_cmd.h @@ -96,6 +96,12 @@ class LDBCommand { ldb_options_ = ldb_options; } + const std::map& TEST_GetOptionMap() { + return option_map_; + } + + const std::vector& TEST_GetFlags() { return flags_; } + virtual bool NoDBOpen() { return false; } virtual ~LDBCommand() { CloseDB(); } diff --git a/tools/ldb_cmd.cc b/tools/ldb_cmd.cc index c82369777..82cb763e6 100644 --- a/tools/ldb_cmd.cc +++ b/tools/ldb_cmd.cc @@ -132,12 +132,19 @@ LDBCommand* LDBCommand::InitFromCmdLineArgs( for (const auto& arg : args) { if (arg[0] == '-' && arg[1] == '-'){ std::vector splits = StringSplit(arg, '='); + // --option_name=option_value if (splits.size() == 2) { std::string optionKey = splits[0].substr(OPTION_PREFIX.size()); parsed_params.option_map[optionKey] = splits[1]; - } else { + } else if (splits.size() == 1) { + // --flag_name std::string optionKey = splits[0].substr(OPTION_PREFIX.size()); parsed_params.flags.push_back(optionKey); + } else { + // --option_name=option_value, option_value contains '=' + std::string optionKey = splits[0].substr(OPTION_PREFIX.size()); + parsed_params.option_map[optionKey] = + arg.substr(splits[0].length() + 1); } } else { cmdTokens.push_back(arg); diff --git a/tools/ldb_cmd_test.cc b/tools/ldb_cmd_test.cc index 9de8a99c3..3b7099533 100644 --- a/tools/ldb_cmd_test.cc +++ b/tools/ldb_cmd_test.cc @@ -81,6 +81,43 @@ TEST_F(LdbCmdTest, MemEnv) { tool.Run(3, argv, opts); } +TEST_F(LdbCmdTest, OptionParsing) { + // test parsing flags + { + std::vector args; + args.push_back("scan"); + args.push_back("--ttl"); + args.push_back("--timestamp"); + LDBCommand* command = rocksdb::LDBCommand::InitFromCmdLineArgs( + args, Options(), LDBOptions(), nullptr); + const std::vector flags = command->TEST_GetFlags(); + EXPECT_EQ(flags.size(), 2); + EXPECT_EQ(flags[0], "ttl"); + EXPECT_EQ(flags[1], "timestamp"); + delete command; + } + // test parsing options which contains equal sign in the option value + { + std::vector args; + args.push_back("scan"); + args.push_back("--db=/dev/shm/ldbtest/"); + args.push_back( + "--from='abcd/efg/hijk/lmn/" + "opq:__rst.uvw.xyz?a=3+4+bcd+efghi&jk=lm_no&pq=rst-0&uv=wx-8&yz=a&bcd_" + "ef=gh.ijk'"); + LDBCommand* command = rocksdb::LDBCommand::InitFromCmdLineArgs( + args, Options(), LDBOptions(), nullptr); + const std::map option_map = + command->TEST_GetOptionMap(); + EXPECT_EQ(option_map.at("db"), "/dev/shm/ldbtest/"); + EXPECT_EQ(option_map.at("from"), + "'abcd/efg/hijk/lmn/" + "opq:__rst.uvw.xyz?a=3+4+bcd+efghi&jk=lm_no&pq=rst-0&uv=wx-8&yz=" + "a&bcd_ef=gh.ijk'"); + delete command; + } +} + } // namespace rocksdb int main(int argc, char** argv) {