// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). // #pragma once #include #include #include #include #include #include #include #include #include "rocksdb/convenience.h" #include "rocksdb/env.h" #include "rocksdb/iterator.h" #include "rocksdb/ldb_tool.h" #include "rocksdb/options.h" #include "rocksdb/slice.h" #include "rocksdb/utilities/db_ttl.h" #include "rocksdb/utilities/ldb_cmd_execute_result.h" namespace ROCKSDB_NAMESPACE { class LDBCommand { public: // Command-line arguments static const std::string ARG_ENV_URI; static const std::string ARG_FS_URI; static const std::string ARG_DB; static const std::string ARG_PATH; static const std::string ARG_SECONDARY_PATH; static const std::string ARG_HEX; static const std::string ARG_KEY_HEX; static const std::string ARG_VALUE_HEX; static const std::string ARG_CF_NAME; static const std::string ARG_TTL; static const std::string ARG_TTL_START; static const std::string ARG_TTL_END; static const std::string ARG_TIMESTAMP; static const std::string ARG_TRY_LOAD_OPTIONS; static const std::string ARG_IGNORE_UNKNOWN_OPTIONS; static const std::string ARG_FROM; static const std::string ARG_TO; static const std::string ARG_MAX_KEYS; static const std::string ARG_BLOOM_BITS; static const std::string ARG_FIX_PREFIX_LEN; static const std::string ARG_COMPRESSION_TYPE; static const std::string ARG_COMPRESSION_MAX_DICT_BYTES; static const std::string ARG_BLOCK_SIZE; static const std::string ARG_AUTO_COMPACTION; static const std::string ARG_DB_WRITE_BUFFER_SIZE; static const std::string ARG_WRITE_BUFFER_SIZE; static const std::string ARG_FILE_SIZE; static const std::string ARG_CREATE_IF_MISSING; static const std::string ARG_NO_VALUE; static const std::string ARG_DISABLE_CONSISTENCY_CHECKS; static const std::string ARG_ENABLE_BLOB_FILES; static const std::string ARG_MIN_BLOB_SIZE; static const std::string ARG_BLOB_FILE_SIZE; static const std::string ARG_BLOB_COMPRESSION_TYPE; static const std::string ARG_ENABLE_BLOB_GARBAGE_COLLECTION; static const std::string ARG_BLOB_GARBAGE_COLLECTION_AGE_CUTOFF; static const std::string ARG_BLOB_GARBAGE_COLLECTION_FORCE_THRESHOLD; static const std::string ARG_BLOB_COMPACTION_READAHEAD_SIZE; static const std::string ARG_BLOB_FILE_STARTING_LEVEL; static const std::string ARG_PREPOPULATE_BLOB_CACHE; static const std::string ARG_DECODE_BLOB_INDEX; static const std::string ARG_DUMP_UNCOMPRESSED_BLOBS; static const std::string ARG_INTERACTIVE; struct ParsedParams { std::string cmd; std::vector cmd_params; std::map option_map; std::vector flags; }; static LDBCommand* SelectCommand(const ParsedParams& parsed_parms); static LDBCommand* InitFromCmdLineArgs( const std::vector& args, const Options& options, const LDBOptions& ldb_options, const std::vector* column_families, const std::function& selector = SelectCommand); static LDBCommand* InitFromCmdLineArgs( int argc, char const* const* argv, const Options& options, const LDBOptions& ldb_options, const std::vector* column_families); bool ValidateCmdLineOptions(); virtual void PrepareOptions(); virtual void OverrideBaseOptions(); virtual void OverrideBaseCFOptions(ColumnFamilyOptions* cf_opts); virtual void SetDBOptions(Options options) { options_ = options; } virtual void SetColumnFamilies( const std::vector* column_families) { if (column_families != nullptr) { column_families_ = *column_families; } else { column_families_.clear(); } } void SetLDBOptions(const LDBOptions& ldb_options) { 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(); } /* Run the command, and return the execute result. */ void Run(); virtual void DoCommand() = 0; LDBCommandExecuteResult GetExecuteState() { return exec_state_; } void ClearPreviousRunState() { exec_state_.Reset(); } // Consider using Slice::DecodeHex directly instead if you don't need the // 0x prefix static std::string HexToString(const std::string& str); // Consider using Slice::ToString(true) directly instead if // you don't need the 0x prefix static std::string StringToHex(const std::string& str); static const char* DELIM; protected: LDBCommandExecuteResult exec_state_; std::string env_uri_; std::string fs_uri_; std::string db_path_; // If empty, open DB as primary. If non-empty, open the DB as secondary // with this secondary path. When running against a database opened by // another process, ldb wll leave the source directory completely intact. std::string secondary_path_; std::string column_family_name_; DB* db_; DBWithTTL* db_ttl_; std::map cf_handles_; /** * true implies that this command can work if the db is opened in read-only * mode. */ bool is_read_only_; /** If true, the key is input/output as hex in get/put/scan/delete etc. */ bool is_key_hex_; /** If true, the value is input/output as hex in get/put/scan/delete etc. */ bool is_value_hex_; /** If true, the value is treated as timestamp suffixed */ bool is_db_ttl_; // If true, the kvs are output with their insert/modify timestamp in a ttl db bool timestamp_; // If true, try to construct options from DB's option files. bool try_load_options_; // The value passed to options.force_consistency_checks. bool force_consistency_checks_; bool enable_blob_files_; bool enable_blob_garbage_collection_; bool create_if_missing_; // If true will not print values for dump, idump, scan bool is_no_value_; /** * Map of options passed on the command-line. */ const std::map option_map_; /** * Flags passed on the command-line. */ const std::vector flags_; /** List of command-line options valid for this command */ const std::vector valid_cmd_line_options_; /** Shared pointer to underlying environment if applicable **/ std::shared_ptr env_guard_; /** ttl value for dbwithttl::open **/ int32_t ttl_; bool ParseKeyValue(const std::string& line, std::string* key, std::string* value, bool is_key_hex, bool is_value_hex); LDBCommand(const std::map& options, const std::vector& flags, bool is_read_only, const std::vector& valid_cmd_line_options); void OpenDB(); void CloseDB(); ColumnFamilyHandle* GetCfHandle(); static std::string PrintKeyValue(const std::string& key, const std::string& value, bool is_key_hex, bool is_value_hex); static std::string PrintKeyValue(const std::string& key, const std::string& value, bool is_hex); /** * Return true if the specified flag is present in the specified flags vector */ static bool IsFlagPresent(const std::vector& flags, const std::string& flag) { return (std::find(flags.begin(), flags.end(), flag) != flags.end()); } static std::string HelpRangeCmdArgs(); /** * A helper function that returns a list of command line options * used by this command. It includes the common options and the ones * passed in. */ static std::vector BuildCmdLineOptions( std::vector options); bool ParseIntOption(const std::map& options, const std::string& option, int& value, LDBCommandExecuteResult& exec_state); bool ParseDoubleOption(const std::map& options, const std::string& option, double& value, LDBCommandExecuteResult& exec_state); bool ParseStringOption(const std::map& options, const std::string& option, std::string* value); bool ParseCompressionTypeOption( const std::map& options, const std::string& option, CompressionType& value, LDBCommandExecuteResult& exec_state); /** * Returns the value of the specified option as a boolean. * default_val is used if the option is not found in options. * Throws an exception if the value of the option is not * "true" or "false" (case insensitive). */ bool ParseBooleanOption(const std::map& options, const std::string& option, bool default_val); Options options_; std::vector column_families_; ConfigOptions config_options_; LDBOptions ldb_options_; private: /** * Interpret command line options and flags to determine if the key * should be input/output in hex. */ bool IsKeyHex(const std::map& options, const std::vector& flags); /** * Interpret command line options and flags to determine if the value * should be input/output in hex. */ bool IsValueHex(const std::map& options, const std::vector& flags); bool IsTryLoadOptions(const std::map& options, const std::vector& flags); /** * Converts val to a boolean. * val must be either true or false (case insensitive). * Otherwise an exception is thrown. */ bool StringToBool(std::string val); }; class LDBCommandRunner { public: static void PrintHelp(const LDBOptions& ldb_options, const char* exec_name, bool to_stderr = true); // Returns the status code to return. 0 is no error. static int RunCommand( int argc, char const* const* argv, Options options, const LDBOptions& ldb_options, const std::vector* column_families); }; } // namespace ROCKSDB_NAMESPACE