YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/rocksdb/tools/ldb_cmd.h
Line
Count
Source (jump to first uncovered line)
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under the BSD-style license found in the
3
//  LICENSE file in the root directory of this source tree. An additional grant
4
//  of patent rights can be found in the PATENTS file in the same directory.
5
//
6
// The following only applies to changes made to this file as part of YugaByte development.
7
//
8
// Portions Copyright (c) YugaByte, Inc.
9
//
10
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
11
// in compliance with the License.  You may obtain a copy of the License at
12
//
13
// http://www.apache.org/licenses/LICENSE-2.0
14
//
15
// Unless required by applicable law or agreed to in writing, software distributed under the License
16
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17
// or implied.  See the License for the specific language governing permissions and limitations
18
// under the License.
19
//
20
#ifndef YB_ROCKSDB_TOOLS_LDB_CMD_H
21
#define YB_ROCKSDB_TOOLS_LDB_CMD_H
22
23
#pragma once
24
25
#ifndef ROCKSDB_LITE
26
27
#include <stdlib.h>
28
#include <stdio.h>
29
30
#include <string>
31
#include <iostream>
32
#include <sstream>
33
#include <algorithm>
34
#include <vector>
35
#include <map>
36
37
#include "yb/encryption/header_manager_impl.h"
38
#include "yb/encryption/universe_key_manager.h"
39
40
#include "yb/rocksdb/db/version_set.h"
41
#include "yb/rocksdb/env.h"
42
#include "yb/rocksdb/iterator.h"
43
#include "yb/rocksdb/ldb_tool.h"
44
#include "yb/rocksdb/options.h"
45
#include "yb/rocksdb/utilities/db_ttl.h"
46
#include "yb/rocksdb/tools/ldb_cmd_execute_result.h"
47
#include "yb/rocksdb/util/logging.h"
48
#include "yb/rocksdb/utilities/ttl/db_ttl_impl.h"
49
#include "yb/util/slice.h"
50
#include "yb/util/string_util.h"
51
#include "yb/rocksutil/rocksdb_encrypted_file_factory.h"
52
53
using std::string;
54
using std::map;
55
using std::vector;
56
using std::ostringstream;
57
58
namespace rocksdb {
59
60
class LDBCommand {
61
 public:
62
  // Command-line arguments
63
  static const string ARG_DB;
64
  static const string ARG_PATH;
65
  static const string ARG_HEX;
66
  static const string ARG_KEY_HEX;
67
  static const string ARG_VALUE_HEX;
68
  static const string ARG_CF_NAME;
69
  static const string ARG_TTL;
70
  static const string ARG_TTL_START;
71
  static const string ARG_TTL_END;
72
  static const string ARG_TIMESTAMP;
73
  static const string ARG_FROM;
74
  static const string ARG_TO;
75
  static const string ARG_MAX_KEYS;
76
  static const string ARG_BLOOM_BITS;
77
  static const string ARG_FIX_PREFIX_LEN;
78
  static const string ARG_COMPRESSION_TYPE;
79
  static const string ARG_BLOCK_SIZE;
80
  static const string ARG_AUTO_COMPACTION;
81
  static const string ARG_DB_WRITE_BUFFER_SIZE;
82
  static const string ARG_WRITE_BUFFER_SIZE;
83
  static const string ARG_FILE_SIZE;
84
  static const string ARG_CREATE_IF_MISSING;
85
  static const string ARG_NO_VALUE;
86
  static const string ARG_UNIVERSE_KEY_FILE;
87
  static const string ARG_ONLY_VERIFY_CHECKSUMS;
88
89
  static LDBCommand* InitFromCmdLineArgs(
90
      const vector<string>& args, const Options& options,
91
      const LDBOptions& ldb_options,
92
      const std::vector<ColumnFamilyDescriptor>* column_families);
93
94
  static LDBCommand* InitFromCmdLineArgs(
95
      int argc, char** argv, const Options& options,
96
      const LDBOptions& ldb_options,
97
      const std::vector<ColumnFamilyDescriptor>* column_families);
98
99
  bool ValidateCmdLineOptions();
100
101
  virtual Options PrepareOptionsForOpenDB();
102
103
12
  virtual void SetDBOptions(Options options) {
104
12
    options_ = options;
105
12
  }
106
107
  virtual void SetColumnFamilies(
108
0
      const std::vector<ColumnFamilyDescriptor>* column_families) {
109
0
    if (column_families != nullptr) {
110
0
      column_families_ = *column_families;
111
0
    } else {
112
0
      column_families_.clear();
113
0
    }
114
0
  }
115
116
12
  void SetLDBOptions(const LDBOptions& ldb_options) {
117
12
    ldb_options_ = ldb_options;
118
12
  }
119
120
4
  virtual bool NoDBOpen() {
121
4
    return false;
122
4
  }
123
124
12
  virtual ~LDBCommand() { CloseDB(); }
125
126
  /* Run the command, and return the execute result. */
127
12
  void Run() {
128
12
    if (!exec_state_.IsNotStarted()) {
129
0
      return;
130
0
    }
131
132
12
    if (db_ == nullptr && !NoDBOpen()) {
133
2
      OpenDB();
134
2
    }
135
136
    // We'll intentionally proceed even if the DB can't be opened because users
137
    // can also specify a filename, not just a directory.
138
12
    DoCommand();
139
140
12
    if (exec_state_.IsNotStarted()) {
141
12
      exec_state_ = LDBCommandExecuteResult::Succeed("");
142
12
    }
143
144
12
    if (db_ != nullptr) {
145
2
      CloseDB ();
146
2
    }
147
12
  }
148
149
  virtual void DoCommand() = 0;
150
151
12
  LDBCommandExecuteResult GetExecuteState() {
152
12
    return exec_state_;
153
12
  }
154
155
0
  void ClearPreviousRunState() {
156
0
    exec_state_.Reset();
157
0
  }
158
159
26
  static string HexToString(const string& str) {
160
26
    std::string::size_type len = str.length();
161
26
    string parsed;
162
26
    static const char* const hexas = "0123456789ABCDEF";
163
26
    parsed.reserve(len / 2);
164
165
26
    if (len < 2 || str[0] != '0' || 
str[1] != 'x'22
) {
166
4
      fprintf(stderr, "Invalid hex input %s.  Must start with 0x\n",
167
4
              str.c_str());
168
4
      throw "Invalid hex input";
169
4
    }
170
171
38
    
for (unsigned int i = 2; 22
i < len;
i += 216
) {
172
30
      char a = static_cast<char>(toupper(str[i]));
173
30
      const char* p = std::lower_bound(hexas, hexas + 16, a);
174
30
      if (*p != a) {
175
8
        throw "Invalid hex value";
176
8
      }
177
178
22
      if (i + 1 >= len) {
179
        // if odd number of chars than we just hit end of string
180
4
        parsed.push_back(static_cast<char>(p - hexas));
181
4
        break;
182
4
      }
183
184
18
      char b = static_cast<char>(toupper(str[i + 1]));
185
18
      const char* q = std::lower_bound(hexas, hexas + 16, b);
186
18
      if (*q == b) {
187
        // pairwise compute decimal value from hex
188
16
        parsed.push_back(static_cast<char>(((p - hexas) << 4) | (q - hexas)));
189
16
      } else {
190
2
        throw "Invalid hex value";
191
2
      }
192
18
    }
193
12
    return parsed;
194
22
  }
195
196
0
  static string StringToHex(const string& str) {
197
0
    string result = "0x";
198
0
    char buf[10];
199
0
    for (size_t i = 0; i < str.length(); i++) {
200
0
      snprintf(buf, sizeof(buf), "%02X", (unsigned char)str[i]);
201
0
      result += buf;
202
0
    }
203
0
    return result;
204
0
  }
205
206
  static const char* DELIM;
207
208
 protected:
209
210
  LDBCommandExecuteResult exec_state_;
211
  string db_path_;
212
  string column_family_name_;
213
  DB* db_;
214
  DBWithTTL* db_ttl_;
215
  std::map<std::string, ColumnFamilyHandle*> cf_handles_;
216
217
  /**
218
   * true implies that this command can work if the db is opened in read-only
219
   * mode.
220
   */
221
  bool is_read_only_;
222
223
  /** If true, the key is input/output as hex in get/put/scan/delete etc. */
224
  bool is_key_hex_;
225
226
  /** If true, the value is input/output as hex in get/put/scan/delete etc. */
227
  bool is_value_hex_;
228
229
  /** If true, the value is treated as timestamp suffixed */
230
  bool is_db_ttl_;
231
232
  // If true, the kvs are output with their insert/modify timestamp in a ttl db
233
  bool timestamp_;
234
235
  /**
236
   * Map of options passed on the command-line.
237
   */
238
  const map<string, string> option_map_;
239
240
  /**
241
   * Flags passed on the command-line.
242
   */
243
  const vector<string> flags_;
244
245
  /** List of command-line options valid for this command */
246
  const vector<string> valid_cmd_line_options_;
247
248
  std::unique_ptr<yb::encryption::UniverseKeyManager> universe_key_manager_;
249
  std::unique_ptr<rocksdb::Env> env_;
250
251
  bool ParseKeyValue(const string& line, string* key, string* value,
252
                      bool is_key_hex, bool is_value_hex);
253
254
  LDBCommand(const map<string, string>& options, const vector<string>& flags,
255
             bool is_read_only, const vector<string>& valid_cmd_line_options) :
256
      db_(nullptr),
257
      is_read_only_(is_read_only),
258
      is_key_hex_(false),
259
      is_value_hex_(false),
260
      is_db_ttl_(false),
261
      timestamp_(false),
262
      option_map_(options),
263
      flags_(flags),
264
12
      valid_cmd_line_options_(valid_cmd_line_options) {
265
266
12
    map<string, string>::const_iterator itr = options.find(ARG_DB);
267
12
    if (itr != options.end()) {
268
12
      db_path_ = itr->second;
269
12
    }
270
271
12
    itr = options.find(ARG_UNIVERSE_KEY_FILE);
272
12
    if (itr != options.end()) {
273
2
      vector<string> splits = StringSplit(itr->second, ':');
274
2
      if (splits.size() != 2) {
275
0
        LOG(FATAL) << yb::Format("Could not split $0 by ':' into a key id and key file",
276
0
                                 itr->second);
277
0
      }
278
2
      string key_data;
279
2
      auto key_id = splits[0];
280
2
      auto key_path = splits[1];
281
2
      Status s = ReadFileToString(Env::Default(), key_path, &key_data);
282
2
      if(!s.ok()) {
283
0
        LOG(FATAL) << yb::Format("Could not read file at path $0: $1", key_path, s.ToString());
284
0
      }
285
2
      auto res = yb::encryption::UniverseKeyManager::FromKey(key_id, yb::Slice(key_data));
286
2
      if (!res.ok()) {
287
0
        LOG(FATAL) << "Could not create universe key manager: " << res.status().ToString();
288
0
      }
289
2
      universe_key_manager_ = std::move(*res);
290
2
      env_ = yb::NewRocksDBEncryptedEnv(
291
2
          yb::encryption::DefaultHeaderManager(universe_key_manager_.get()));
292
2
    }
293
294
12
    itr = options.find(ARG_CF_NAME);
295
12
    if (itr != options.end()) {
296
0
      column_family_name_ = itr->second;
297
12
    } else {
298
12
      column_family_name_ = kDefaultColumnFamilyName;
299
12
    }
300
301
12
    is_key_hex_ = IsKeyHex(options, flags);
302
12
    is_value_hex_ = IsValueHex(options, flags);
303
12
    is_db_ttl_ = IsFlagPresent(flags, ARG_TTL);
304
12
    timestamp_ = IsFlagPresent(flags, ARG_TIMESTAMP);
305
12
  }
306
307
7
  void OpenDB() {
308
7
    Options opt = PrepareOptionsForOpenDB();
309
7
    if (!exec_state_.IsNotStarted()) {
310
0
      return;
311
0
    }
312
    // Open the DB.
313
7
    Status st;
314
7
    std::vector<ColumnFamilyHandle*> handles_opened;
315
7
    if (is_db_ttl_) {
316
      // ldb doesn't yet support TTL DB with multiple column families
317
0
      if (!column_family_name_.empty() || !column_families_.empty()) {
318
0
        exec_state_ = LDBCommandExecuteResult::Failed(
319
0
            "ldb doesn't support TTL DB with multiple column families");
320
0
      }
321
0
      if (is_read_only_) {
322
0
        st = DBWithTTL::Open(opt, db_path_, &db_ttl_, 0, true);
323
0
      } else {
324
0
        st = DBWithTTL::Open(opt, db_path_, &db_ttl_);
325
0
      }
326
0
      db_ = db_ttl_;
327
7
    } else {
328
7
      if (column_families_.empty()) {
329
        // Try to figure out column family lists
330
7
        std::vector<std::string> cf_list;
331
7
        st = DB::ListColumnFamilies(DBOptions(), db_path_, &cf_list);
332
        // There is possible the DB doesn't exist yet, for "create if not
333
        // "existing case". The failure is ignored here. We rely on DB::Open()
334
        // to give us the correct error message for problem with opening
335
        // existing DB.
336
7
        if (st.ok() && 
cf_list.size() > 16
) {
337
          // Ignore single column family DB.
338
0
          for (auto cf_name : cf_list) {
339
0
            column_families_.emplace_back(cf_name, opt);
340
0
          }
341
0
        }
342
7
      }
343
7
      if (is_read_only_) {
344
2
        if (column_families_.empty()) {
345
2
          st = DB::OpenForReadOnly(opt, db_path_, &db_);
346
2
        } else {
347
0
          st = DB::OpenForReadOnly(opt, db_path_, column_families_,
348
0
                                   &handles_opened, &db_);
349
0
        }
350
5
      } else {
351
5
        if (column_families_.empty()) {
352
5
          st = DB::Open(opt, db_path_, &db_);
353
5
        } else {
354
0
          st = DB::Open(opt, db_path_, column_families_, &handles_opened, &db_);
355
0
        }
356
5
      }
357
7
    }
358
7
    if (!st.ok()) {
359
0
      string msg = st.ToString();
360
0
      exec_state_ = LDBCommandExecuteResult::Failed(msg);
361
7
    } else if (!handles_opened.empty()) {
362
0
      assert(handles_opened.size() == column_families_.size());
363
0
      bool found_cf_name = false;
364
0
      for (size_t i = 0; i < handles_opened.size(); i++) {
365
0
        cf_handles_[column_families_[i].name] = handles_opened[i];
366
0
        if (column_family_name_ == column_families_[i].name) {
367
0
          found_cf_name = true;
368
0
        }
369
0
      }
370
0
      if (!found_cf_name) {
371
0
        exec_state_ = LDBCommandExecuteResult::Failed(
372
0
            "Non-existing column family " + column_family_name_);
373
0
        CloseDB();
374
0
      }
375
7
    } else {
376
      // We successfully opened DB in single column family mode.
377
7
      assert(column_families_.empty());
378
7
      if (column_family_name_ != kDefaultColumnFamilyName) {
379
0
        exec_state_ = LDBCommandExecuteResult::Failed(
380
0
            "Non-existing column family " + column_family_name_);
381
0
        CloseDB();
382
0
      }
383
7
    }
384
385
0
    options_ = opt;
386
7
  }
387
388
19
  void CloseDB () {
389
19
    if (db_ != nullptr) {
390
7
      for (auto& pair : cf_handles_) {
391
0
        delete pair.second;
392
0
      }
393
7
      delete db_;
394
7
      db_ = nullptr;
395
7
    }
396
19
  }
397
398
7
  ColumnFamilyHandle* GetCfHandle() {
399
7
    if (!cf_handles_.empty()) {
400
0
      auto it = cf_handles_.find(column_family_name_);
401
0
      if (it == cf_handles_.end()) {
402
0
        exec_state_ = LDBCommandExecuteResult::Failed(
403
0
            "Cannot find column family " + column_family_name_);
404
0
      } else {
405
0
        return it->second;
406
0
      }
407
0
    }
408
7
    return db_->DefaultColumnFamily();
409
7
  }
410
411
  static string PrintKeyValue(const string& key, const string& value,
412
0
        bool is_key_hex, bool is_value_hex) {
413
0
    string result;
414
0
    result.append(is_key_hex ? StringToHex(key) : key);
415
0
    result.append(DELIM);
416
0
    result.append(is_value_hex ? StringToHex(value) : value);
417
0
    return result;
418
0
  }
419
420
  static string PrintKeyValue(const string& key, const string& value,
421
0
        bool is_hex) {
422
0
    return PrintKeyValue(key, value, is_hex, is_hex);
423
0
  }
424
425
  /**
426
   * Return true if the specified flag is present in the specified flags vector
427
   */
428
80
  static bool IsFlagPresent(const vector<string>& flags, const string& flag) {
429
80
    return (std::find(flags.begin(), flags.end(), flag) != flags.end());
430
80
  }
431
432
0
  static string HelpRangeCmdArgs() {
433
0
    ostringstream str_stream;
434
0
    str_stream << " ";
435
0
    str_stream << "[--" << ARG_FROM << "] ";
436
0
    str_stream << "[--" << ARG_TO << "] ";
437
0
    return str_stream.str();
438
0
  }
439
440
  /**
441
   * A helper function that returns a list of command line options
442
   * used by this command.  It includes the common options and the ones
443
   * passed in.
444
   */
445
12
  static vector<string> BuildCmdLineOptions(vector<string> options) {
446
12
    vector<string> ret = {ARG_DB, ARG_BLOOM_BITS, ARG_BLOCK_SIZE,
447
12
                          ARG_AUTO_COMPACTION, ARG_COMPRESSION_TYPE,
448
12
                          ARG_WRITE_BUFFER_SIZE, ARG_FILE_SIZE,
449
12
                          ARG_FIX_PREFIX_LEN, ARG_CF_NAME, ARG_UNIVERSE_KEY_FILE};
450
12
    ret.insert(ret.end(), options.begin(), options.end());
451
12
    return ret;
452
12
  }
453
454
  bool ParseIntOption(const map<string, string>& options, const string& option,
455
                      int& value, LDBCommandExecuteResult& exec_state); // NOLINT
456
457
  bool ParseStringOption(const map<string, string>& options,
458
                         const string& option, string* value);
459
460
  Options options_;
461
  std::vector<ColumnFamilyDescriptor> column_families_;
462
  LDBOptions ldb_options_;
463
464
 private:
465
466
  /**
467
   * Interpret command line options and flags to determine if the key
468
   * should be input/output in hex.
469
   */
470
  bool IsKeyHex(const map<string, string>& options,
471
12
      const vector<string>& flags) {
472
12
    return (IsFlagPresent(flags, ARG_HEX) ||
473
12
        IsFlagPresent(flags, ARG_KEY_HEX) ||
474
12
        ParseBooleanOption(options, ARG_HEX, false) ||
475
12
        ParseBooleanOption(options, ARG_KEY_HEX, false));
476
12
  }
477
478
  /**
479
   * Interpret command line options and flags to determine if the value
480
   * should be input/output in hex.
481
   */
482
  bool IsValueHex(const map<string, string>& options,
483
12
      const vector<string>& flags) {
484
12
    return (IsFlagPresent(flags, ARG_HEX) ||
485
12
          IsFlagPresent(flags, ARG_VALUE_HEX) ||
486
12
          ParseBooleanOption(options, ARG_HEX, false) ||
487
12
          ParseBooleanOption(options, ARG_VALUE_HEX, false));
488
12
  }
489
490
  /**
491
   * Returns the value of the specified option as a boolean.
492
   * default_val is used if the option is not found in options.
493
   * Throws an exception if the value of the option is not
494
   * "true" or "false" (case insensitive).
495
   */
496
  bool ParseBooleanOption(const map<string, string>& options,
497
48
      const string& option, bool default_val) {
498
499
48
    map<string, string>::const_iterator itr = options.find(option);
500
48
    if (itr != options.end()) {
501
0
      string option_val = itr->second;
502
0
      return StringToBool(itr->second);
503
0
    }
504
48
    return default_val;
505
48
  }
506
507
  /**
508
   * Converts val to a boolean.
509
   * val must be either true or false (case insensitive).
510
   * Otherwise an exception is thrown.
511
   */
512
0
  bool StringToBool(string val) {
513
0
    std::transform(val.begin(), val.end(), val.begin(),
514
0
                   [](char ch)->char { return static_cast<char>(::tolower(ch)); });
515
516
0
    if (val == "true") {
517
0
      return true;
518
0
    } else if (val == "false") {
519
0
      return false;
520
0
    } else {
521
0
      throw "Invalid value for boolean argument";
522
0
    }
523
0
  }
524
525
  static LDBCommand* SelectCommand(
526
    const string& cmd,
527
    const vector<string>& cmdParams,
528
    const map<string, string>& option_map,
529
    const vector<string>& flags
530
  );
531
532
};
533
534
class CompactorCommand: public LDBCommand {
535
 public:
536
10
  static string Name() { return "compact"; }
537
538
  CompactorCommand(const vector<string>& params,
539
      const map<string, string>& options, const vector<string>& flags);
540
541
  static void Help(string& ret); // NOLINT
542
543
  virtual void DoCommand() override;
544
545
 private:
546
  bool null_from_;
547
  string from_;
548
  bool null_to_;
549
  string to_;
550
};
551
552
class DBFileDumperCommand : public LDBCommand {
553
 public:
554
2
  static string Name() { return "dump_live_files"; }
555
556
  DBFileDumperCommand(const vector<string>& params,
557
                      const map<string, string>& options,
558
                      const vector<string>& flags);
559
560
  static void Help(string& ret); // NOLINT
561
562
  virtual void DoCommand() override;
563
};
564
565
class DBDumperCommand: public LDBCommand {
566
 public:
567
2
  static string Name() { return "dump"; }
568
569
  DBDumperCommand(const vector<string>& params,
570
      const map<string, string>& options, const vector<string>& flags);
571
572
  static void Help(string& ret); // NOLINT
573
574
  virtual void DoCommand() override;
575
576
 private:
577
  /**
578
   * Extract file name from the full path. We handle both the forward slash (/)
579
   * and backslash (\) to make sure that different OS-s are supported.
580
  */
581
0
  static string GetFileNameFromPath(const string& s) {
582
0
    std::size_t n = s.find_last_of("/\\");
583
584
0
    if (std::string::npos == n) {
585
0
      return s;
586
0
    } else {
587
0
      return s.substr(n + 1);
588
0
    }
589
0
  }
590
591
  void DoDumpCommand();
592
593
  bool null_from_;
594
  string from_;
595
  bool null_to_;
596
  string to_;
597
  int max_keys_;
598
  string delim_;
599
  bool count_only_;
600
  bool count_delim_;
601
  bool print_stats_;
602
  string path_;
603
604
  static const string ARG_COUNT_ONLY;
605
  static const string ARG_COUNT_DELIM;
606
  static const string ARG_STATS;
607
  static const string ARG_TTL_BUCKET;
608
};
609
610
class InternalDumpCommand: public LDBCommand {
611
 public:
612
2
  static string Name() { return "idump"; }
613
614
  InternalDumpCommand(const vector<string>& params,
615
                      const map<string, string>& options,
616
                      const vector<string>& flags);
617
618
  static void Help(string& ret); // NOLINT
619
620
  virtual void DoCommand() override;
621
622
 private:
623
  bool has_from_;
624
  string from_;
625
  bool has_to_;
626
  string to_;
627
  int max_keys_;
628
  string delim_;
629
  bool count_only_;
630
  bool count_delim_;
631
  bool print_stats_;
632
  bool is_input_key_hex_;
633
634
  static const string ARG_DELIM;
635
  static const string ARG_COUNT_ONLY;
636
  static const string ARG_COUNT_DELIM;
637
  static const string ARG_STATS;
638
  static const string ARG_INPUT_KEY_HEX;
639
};
640
641
class DBLoaderCommand: public LDBCommand {
642
 public:
643
2
  static string Name() { return "load"; }
644
645
  DBLoaderCommand(string& db_name, vector<string>& args); // NOLINT
646
647
  DBLoaderCommand(const vector<string>& params,
648
      const map<string, string>& options, const vector<string>& flags);
649
650
  static void Help(string& ret); // NOLINT
651
  virtual void DoCommand() override;
652
653
  virtual Options PrepareOptionsForOpenDB() override;
654
655
 private:
656
  bool create_if_missing_;
657
  bool disable_wal_;
658
  bool bulk_load_;
659
  bool compact_;
660
661
  static const string ARG_DISABLE_WAL;
662
  static const string ARG_BULK_LOAD;
663
  static const string ARG_COMPACT;
664
};
665
666
class ManifestDumpCommand: public LDBCommand {
667
 public:
668
2
  static string Name() { return "manifest_dump"; }
669
670
  ManifestDumpCommand(const vector<string>& params,
671
      const map<string, string>& options, const vector<string>& flags);
672
673
  static void Help(string& ret); // NOLINT
674
  virtual void DoCommand() override;
675
676
0
  virtual bool NoDBOpen() override { return true; }
677
678
 private:
679
  bool verbose_;
680
  string path_;
681
682
  static const string ARG_VERBOSE;
683
  static const string ARG_JSON;
684
  static const string ARG_PATH;
685
};
686
687
class ListColumnFamiliesCommand : public LDBCommand {
688
 public:
689
2
  static string Name() { return "list_column_families"; }
690
691
  ListColumnFamiliesCommand(const vector<string>& params,
692
                            const map<string, string>& options,
693
                            const vector<string>& flags);
694
695
  static void Help(string& ret); // NOLINT
696
  virtual void DoCommand() override;
697
698
0
  virtual bool NoDBOpen() override { return true; }
699
700
 private:
701
  string dbname_;
702
};
703
704
class CreateColumnFamilyCommand : public LDBCommand {
705
 public:
706
2
  static string Name() { return "create_column_family"; }
707
708
  CreateColumnFamilyCommand(const vector<string>& params,
709
                            const map<string, string>& options,
710
                            const vector<string>& flags);
711
712
  static void Help(string& ret); // NOLINT
713
  virtual void DoCommand() override;
714
715
0
  virtual bool NoDBOpen() override { return false; }
716
717
 private:
718
  string new_cf_name_;
719
};
720
721
class ReduceDBLevelsCommand : public LDBCommand {
722
 public:
723
10
  static string Name() { return "reduce_levels"; }
724
725
  ReduceDBLevelsCommand(const vector<string>& params,
726
      const map<string, string>& options, const vector<string>& flags);
727
728
  virtual Options PrepareOptionsForOpenDB() override;
729
730
  virtual void DoCommand() override;
731
732
8
  virtual bool NoDBOpen() override { return true; }
733
734
  static void Help(string& msg); // NOLINT
735
736
  static vector<string> PrepareArgs(const string& db_path, int new_levels,
737
      bool print_old_level = false);
738
739
 private:
740
  int old_levels_;
741
  int new_levels_;
742
  bool print_old_levels_;
743
744
  static const string ARG_NEW_LEVELS;
745
  static const string ARG_PRINT_OLD_LEVELS;
746
747
  Status GetOldNumOfLevels(Options& opt, int* levels); // NOLINT
748
};
749
750
class ChangeCompactionStyleCommand : public LDBCommand {
751
 public:
752
2
  static string Name() { return "change_compaction_style"; }
753
754
  ChangeCompactionStyleCommand(const vector<string>& params,
755
      const map<string, string>& options, const vector<string>& flags);
756
757
  virtual Options PrepareOptionsForOpenDB() override;
758
759
  virtual void DoCommand() override;
760
761
  static void Help(string& msg); // NOLINT
762
763
 private:
764
  int old_compaction_style_;
765
  int new_compaction_style_;
766
767
  static const string ARG_OLD_COMPACTION_STYLE;
768
  static const string ARG_NEW_COMPACTION_STYLE;
769
};
770
771
class WALDumperCommand : public LDBCommand {
772
 public:
773
10
  static string Name() { return "dump_wal"; }
774
775
  WALDumperCommand(const vector<string>& params,
776
      const map<string, string>& options, const vector<string>& flags);
777
778
0
  virtual bool NoDBOpen() override { return true; }
779
780
  static void Help(string& ret); // NOLINT
781
  virtual void DoCommand() override;
782
783
 private:
784
  bool print_header_;
785
  string wal_file_;
786
  bool print_values_;
787
788
  static const string ARG_WAL_FILE;
789
  static const string ARG_PRINT_HEADER;
790
  static const string ARG_PRINT_VALUE;
791
};
792
793
794
class GetCommand : public LDBCommand {
795
 public:
796
12
  static string Name() { return "get"; }
797
798
  GetCommand(const vector<string>& params, const map<string, string>& options,
799
      const vector<string>& flags);
800
801
  virtual void DoCommand() override;
802
803
  static void Help(string& ret); // NOLINT
804
805
 private:
806
  string key_;
807
};
808
809
class ApproxSizeCommand : public LDBCommand {
810
 public:
811
10
  static string Name() { return "approxsize"; }
812
813
  ApproxSizeCommand(const vector<string>& params,
814
      const map<string, string>& options, const vector<string>& flags);
815
816
  virtual void DoCommand() override;
817
818
  static void Help(string& ret); // NOLINT
819
820
 private:
821
  string start_key_;
822
  string end_key_;
823
};
824
825
class BatchPutCommand : public LDBCommand {
826
 public:
827
12
  static string Name() { return "batchput"; }
828
829
  BatchPutCommand(const vector<string>& params,
830
      const map<string, string>& options, const vector<string>& flags);
831
832
  virtual void DoCommand() override;
833
834
  static void Help(string& ret); // NOLINT
835
836
  virtual Options PrepareOptionsForOpenDB() override;
837
838
 private:
839
  /**
840
   * The key-values to be inserted.
841
   */
842
  vector<std::pair<string, string>> key_values_;
843
};
844
845
class ScanCommand : public LDBCommand {
846
 public:
847
12
  static string Name() { return "scan"; }
848
849
  ScanCommand(const vector<string>& params, const map<string, string>& options,
850
      const vector<string>& flags);
851
852
  virtual void DoCommand() override;
853
854
  static void Help(string& ret); // NOLINT
855
856
 private:
857
  string start_key_;
858
  string end_key_;
859
  bool start_key_specified_;
860
  bool end_key_specified_;
861
  int max_keys_scanned_;
862
  bool no_value_;
863
  bool only_verify_checksums_ = false;
864
};
865
866
class DeleteCommand : public LDBCommand {
867
 public:
868
10
  static string Name() { return "delete"; }
869
870
  DeleteCommand(const vector<string>& params,
871
      const map<string, string>& options, const vector<string>& flags);
872
873
  virtual void DoCommand() override;
874
875
  static void Help(string& ret); // NOLINT
876
877
 private:
878
  string key_;
879
};
880
881
class PutCommand : public LDBCommand {
882
 public:
883
12
  static string Name() { return "put"; }
884
885
  PutCommand(const vector<string>& params, const map<string, string>& options,
886
      const vector<string>& flags);
887
888
  virtual void DoCommand() override;
889
890
  static void Help(string& ret); // NOLINT
891
892
  virtual Options PrepareOptionsForOpenDB() override;
893
894
 private:
895
  string key_;
896
  string value_;
897
};
898
899
/**
900
 * Command that starts up a REPL shell that allows
901
 * get/put/delete.
902
 */
903
class DBQuerierCommand: public LDBCommand {
904
 public:
905
10
  static string Name() { return "query"; }
906
907
  DBQuerierCommand(const vector<string>& params,
908
      const map<string, string>& options, const vector<string>& flags);
909
910
  static void Help(string& ret); // NOLINT
911
912
  virtual void DoCommand() override;
913
914
 private:
915
  static const char* HELP_CMD;
916
  static const char* GET_CMD;
917
  static const char* PUT_CMD;
918
  static const char* DELETE_CMD;
919
};
920
921
class CheckConsistencyCommand : public LDBCommand {
922
 public:
923
2
  static string Name() { return "checkconsistency"; }
924
925
  CheckConsistencyCommand(const vector<string>& params,
926
      const map<string, string>& options, const vector<string>& flags);
927
928
  virtual void DoCommand() override;
929
930
4
  virtual bool NoDBOpen() override { return true; }
931
932
  static void Help(string& ret); // NOLINT
933
};
934
935
} // namespace rocksdb
936
937
#endif  // ROCKSDB_LITE
938
#endif // YB_ROCKSDB_TOOLS_LDB_CMD_H