You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

317 lines
10 KiB

// 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 <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <functional>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#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;
struct ParsedParams {
std::string cmd;
std::vector<std::string> cmd_params;
std::map<std::string, std::string> option_map;
std::vector<std::string> flags;
};
static LDBCommand* SelectCommand(const ParsedParams& parsed_parms);
static LDBCommand* InitFromCmdLineArgs(
const std::vector<std::string>& args, const Options& options,
const LDBOptions& ldb_options,
const std::vector<ColumnFamilyDescriptor>* column_families,
const std::function<LDBCommand*(const ParsedParams&)>& selector =
SelectCommand);
static LDBCommand* InitFromCmdLineArgs(
int argc, char const* const* argv, const Options& options,
const LDBOptions& ldb_options,
const std::vector<ColumnFamilyDescriptor>* 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<ColumnFamilyDescriptor>* 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<std::string, std::string>& TEST_GetOptionMap() {
return option_map_;
}
const std::vector<std::string>& 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<std::string, ColumnFamilyHandle*> 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_;
/**
* Map of options passed on the command-line.
*/
const std::map<std::string, std::string> option_map_;
/**
* Flags passed on the command-line.
*/
const std::vector<std::string> flags_;
/** List of command-line options valid for this command */
const std::vector<std::string> valid_cmd_line_options_;
/** Shared pointer to underlying environment if applicable **/
std::shared_ptr<Env> env_guard_;
bool ParseKeyValue(const std::string& line, std::string* key,
std::string* value, bool is_key_hex, bool is_value_hex);
LDBCommand(const std::map<std::string, std::string>& options,
const std::vector<std::string>& flags, bool is_read_only,
const std::vector<std::string>& 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<std::string>& 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<std::string> BuildCmdLineOptions(
std::vector<std::string> options);
bool ParseIntOption(const std::map<std::string, std::string>& options,
const std::string& option, int& value,
LDBCommandExecuteResult& exec_state);
bool ParseDoubleOption(const std::map<std::string, std::string>& options,
const std::string& option, double& value,
LDBCommandExecuteResult& exec_state);
bool ParseStringOption(const std::map<std::string, std::string>& options,
const std::string& option, std::string* value);
bool ParseCompressionTypeOption(
const std::map<std::string, std::string>& 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<std::string, std::string>& options,
const std::string& option, bool default_val);
Options options_;
std::vector<ColumnFamilyDescriptor> 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<std::string, std::string>& options,
const std::vector<std::string>& flags);
/**
* Interpret command line options and flags to determine if the value
* should be input/output in hex.
*/
bool IsValueHex(const std::map<std::string, std::string>& options,
const std::vector<std::string>& flags);
bool IsTryLoadOptions(const std::map<std::string, std::string>& options,
const std::vector<std::string>& 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<ColumnFamilyDescriptor>* column_families);
};
} // namespace ROCKSDB_NAMESPACE