From 5d30668cabdd9306cfdacf23796a002b07527cf1 Mon Sep 17 00:00:00 2001 From: Yanqin Jin Date: Mon, 24 Jan 2022 20:27:40 -0800 Subject: [PATCH] Remove tools/rdb from main repo (#9399) Summary: This PR is one proposal to resolve https://github.com/facebook/rocksdb/issues/9382. Looking at the code, I can't think of a reason why rdb is an internal component of RocksDB: it does not require any header files NOT in `include/rocksdb`. It's a better idea to host it somewhere else. Plus, rdb requires python2 which is not supported any more. No fixes or improvements will be made, even for potential security bugs (https://www.python.org/doc/sunset-python-2/). Pull Request resolved: https://github.com/facebook/rocksdb/pull/9399 Test Plan: make check Reviewed By: ajkr Differential Revision: D33641965 Pulled By: riversand963 fbshipit-source-id: 2a6a74693e5de36834f355e41d6865db206af48b --- Makefile | 2 +- tools/rdb/.gitignore | 1 - tools/rdb/API.md | 178 -------------- tools/rdb/README.md | 40 --- tools/rdb/binding.gyp | 25 -- tools/rdb/db_wrapper.cc | 523 ---------------------------------------- tools/rdb/db_wrapper.h | 58 ----- tools/rdb/rdb | 3 - tools/rdb/rdb.cc | 14 -- tools/rdb/unit_test.js | 125 ---------- 10 files changed, 1 insertion(+), 968 deletions(-) delete mode 100644 tools/rdb/.gitignore delete mode 100644 tools/rdb/API.md delete mode 100644 tools/rdb/README.md delete mode 100644 tools/rdb/binding.gyp delete mode 100644 tools/rdb/db_wrapper.cc delete mode 100644 tools/rdb/db_wrapper.h delete mode 100755 tools/rdb/rdb delete mode 100644 tools/rdb/rdb.cc delete mode 100644 tools/rdb/unit_test.js diff --git a/Makefile b/Makefile index 551c62b0a..1cf18a5e6 100644 --- a/Makefile +++ b/Makefile @@ -561,7 +561,7 @@ ifneq ($(filter check-headers, $(MAKECMDGOALS)),) # TODO: add/support JNI headers DEV_HEADER_DIRS := $(sort include/ $(dir $(ALL_SOURCES))) # Some headers like in port/ are platform-specific - DEV_HEADERS := $(shell $(FIND) $(DEV_HEADER_DIRS) -type f -name '*.h' | egrep -v 'port/|plugin/|lua/|range_tree/|tools/rdb/db_wrapper.h|include/rocksdb/utilities/env_librados.h') + DEV_HEADERS := $(shell $(FIND) $(DEV_HEADER_DIRS) -type f -name '*.h' | egrep -v 'port/|plugin/|lua/|range_tree/|include/rocksdb/utilities/env_librados.h') else DEV_HEADERS := endif diff --git a/tools/rdb/.gitignore b/tools/rdb/.gitignore deleted file mode 100644 index 378eac25d..000000000 --- a/tools/rdb/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build diff --git a/tools/rdb/API.md b/tools/rdb/API.md deleted file mode 100644 index e9c2e5925..000000000 --- a/tools/rdb/API.md +++ /dev/null @@ -1,178 +0,0 @@ -# JavaScript API - -## DBWrapper - -### Constructor - - # Creates a new database wrapper object - RDB() - -### Open - - # Open a new or existing RocksDB database. - # - # db_name (string) - Location of the database (inside the - # `/tmp` directory). - # column_families (string[]) - Names of additional column families - # beyond the default. If there are no other - # column families, this argument can be - # left off. - # - # Returns true if the database was opened successfully, or false otherwise - db_obj.(db_name, column_families = []) - -### Get - - # Get the value of a given key. - # - # key (string) - Which key to get the value of. - # column_family (string) - Which column family to check for the key. - # This argument can be left off for the default - # column family - # - # Returns the value (string) that is associated with the given key if - # one exists, or null otherwise. - db_obj.get(key, column_family = { default }) - -### Put - - # Associate a value with a key. - # - # key (string) - Which key to associate the value with. - # value (string) - The value to associate with the key. - # column_family (string) - Which column family to put the key-value pair - # in. This argument can be left off for the - # default column family. - # - # Returns true if the key-value pair was successfully stored in the - # database, or false otherwise. - db_obj.put(key, value, column_family = { default }) - -### Delete - - # Delete a value associated with a given key. - # - # key (string) - Which key to delete the value of.. - # column_family (string) - Which column family to check for the key. - # This argument can be left off for the default - # column family - # - # Returns true if an error occurred while trying to delete the key in - # the database, or false otherwise. Note that this is NOT the same as - # whether a value was deleted; in the case of a specified key not having - # a value, this will still return true. Use the `get` method prior to - # this method to check if a value existed before the call to `delete`. - db_obj.delete(key, column_family = { default }) - -### Dump - - # Print out all the key-value pairs in a given column family of the - # database. - # - # column_family (string) - Which column family to dump the pairs from. - # This argument can be left off for the default - # column family. - # - # Returns true if the keys were successfully read from the database, or - # false otherwise. - db_obj.dump(column_family = { default }) - -### WriteBatch - - # Execute an atomic batch of writes (i.e. puts and deletes) to the - # database. - # - # cf_batches (BatchObject[]; see below) - Put and Delete writes grouped - # by column family to execute - # atomically. - # - # Returns true if the argument array was well-formed and was - # successfully written to the database, or false otherwise. - db_obj.writeBatch(cf_batches) - -### CreateColumnFamily - - # Create a new column family for the database. - # - # column_family_name (string) - Name of the new column family. - # - # Returns true if the new column family was successfully created, or - # false otherwise. - db_obj.createColumnFamily(column_family_name) - -### CompactRange - - # Compact the underlying storage for a given range. - # - # In addition to the endpoints of the range, the method is overloaded to - # accept a non-default column family, a set of options, or both. - # - # begin (string) - First key in the range to compact. - # end (string) - Last key in the range to compact. - # options (object) - Contains a subset of the following key-value - # pairs: - # * 'target_level' => int - # * 'target_path_id' => int - # column_family (string) - Which column family to compact the range in. - db_obj.compactRange(begin, end) - db_obj.compactRange(begin, end, options) - db_obj.compactRange(begin, end, column_family) - db_obj.compactRange(begin, end, options, column_family) - - - -### Close - - # Close an a database and free the memory associated with it. - # - # Return null. - # db_obj.close() - - -## BatchObject - -### Structure - -A BatchObject must have at least one of the following key-value pairs: - -* 'put' => Array of ['string1', 'string1'] pairs, each of which signifies that -the key 'string1' should be associated with the value 'string2' -* 'delete' => Array of strings, each of which is a key whose value should be -deleted. - -The following key-value pair is optional: - -* 'column_family' => The name (string) of the column family to apply the -changes to. - -### Examples - - # Writes the key-value pairs 'firstname' => 'Saghm' and - # 'lastname' => 'Rossi' atomically to the database. - db_obj.writeBatch([ - { - put: [ ['firstname', 'Saghm'], ['lastname', 'Rossi'] ] - } - ]); - - - # Deletes the values associated with 'firstname' and 'lastname' in - # the default column family and adds the key 'number_of_people' with - # with the value '2'. Additionally, adds the key-value pair - # 'name' => 'Saghm Rossi' to the column family 'user1' and the pair - # 'name' => 'Matt Blaze' to the column family 'user2'. All writes - # are done atomically. - db_obj.writeBatch([ - { - put: [ ['number_of_people', '2'] ], - delete: ['firstname', 'lastname'] - }, - { - put: [ ['name', 'Saghm Rossi'] ], - column_family: 'user1' - }, - { - put: [ ['name', Matt Blaze'] ], - column_family: 'user2' - } - ]); diff --git a/tools/rdb/README.md b/tools/rdb/README.md deleted file mode 100644 index f69b3f7b1..000000000 --- a/tools/rdb/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# RDB - RocksDB Shell - -RDB is a NodeJS-based shell interface to RocksDB. It can also be used as a -JavaScript binding for RocksDB within a Node application. - -## Setup/Compilation - -### Requirements - -* static RocksDB library (i.e. librocksdb.a) -* libsnappy -* node (tested onv0.10.33, no guarantees on anything else!) -* node-gyp -* python2 (for node-gyp; tested with 2.7.8) - -### Installation - -NOTE: If your default `python` binary is not a version of python2, add -the arguments `--python /path/to/python2` to the `node-gyp` commands. - -1. Make sure you have the static library (i.e. "librocksdb.a") in the root -directory of your rocksdb installation. If not, `cd` there and run -`make static_lib`. - -2. Run `node-gyp configure` to generate the build. - -3. Run `node-gyp build` to compile RDB. - -## Usage - -### Running the shell - -Assuming everything compiled correctly, you can run the `rdb` executable -located in the root of the `tools/rdb` directory to start the shell. The file is -just a shell script that runs the node shell and loads the constructor for the -RDB object into the top-level function `RDB`. - -### JavaScript API - -See `API.md` for how to use RocksDB from the shell. diff --git a/tools/rdb/binding.gyp b/tools/rdb/binding.gyp deleted file mode 100644 index 89145541c..000000000 --- a/tools/rdb/binding.gyp +++ /dev/null @@ -1,25 +0,0 @@ -{ - "targets": [ - { - "target_name": "rdb", - "sources": [ - "rdb.cc", - "db_wrapper.cc", - "db_wrapper.h" - ], - "cflags_cc!": [ - "-fno-exceptions" - ], - "cflags_cc+": [ - "-std=c++11", - ], - "include_dirs+": [ - "../../include" - ], - "libraries": [ - "../../../librocksdb.a", - "-lsnappy" - ], - } - ] -} diff --git a/tools/rdb/db_wrapper.cc b/tools/rdb/db_wrapper.cc deleted file mode 100644 index b3bb9bee9..000000000 --- a/tools/rdb/db_wrapper.cc +++ /dev/null @@ -1,523 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -#include -#include -#include -#include -#include - -#include "db/_wrapper.h" -#include "rocksdb/db.h" -#include "rocksdb/options.h" -#include "rocksdb/slice.h" - -namespace { - void printWithBackSlashes(std::string str) { - for (std::string::size_type i = 0; i < str.size(); i++) { - if (str[i] == '\\' || str[i] == '"') { - std::cout << "\\"; - } - - std::cout << str[i]; - } - } - - bool has_key_for_array(Local obj, std::string key) { - return obj->Has(String::NewSymbol(key.c_str())) && - obj->Get(String::NewSymbol(key.c_str()))->IsArray(); - } -} - -Persistent DBWrapper::constructor; - -DBWrapper::DBWrapper() { - options_.IncreaseParallelism(); - options_.OptimizeLevelStyleCompaction(); - options_.disable_auto_compactions = true; - options_.create_if_missing = true; -} - -DBWrapper::~DBWrapper() { - delete db_; -} - -bool DBWrapper::HasFamilyNamed(std::string& name, DBWrapper* db) { - return db->columnFamilies_.find(name) != db->columnFamilies_.end(); -} - - -void DBWrapper::Init(Handle exports) { - Local tpl = FunctionTemplate::New(New); - tpl->SetClassName(String::NewSymbol("DBWrapper")); - tpl->InstanceTemplate()->SetInternalFieldCount(8); - tpl->PrototypeTemplate()->Set(String::NewSymbol("open"), - FunctionTemplate::New(Open)->GetFunction()); - tpl->PrototypeTemplate()->Set(String::NewSymbol("get"), - FunctionTemplate::New(Get)->GetFunction()); - tpl->PrototypeTemplate()->Set(String::NewSymbol("put"), - FunctionTemplate::New(Put)->GetFunction()); - tpl->PrototypeTemplate()->Set(String::NewSymbol("delete"), - FunctionTemplate::New(Delete)->GetFunction()); - tpl->PrototypeTemplate()->Set(String::NewSymbol("dump"), - FunctionTemplate::New(Dump)->GetFunction()); - tpl->PrototypeTemplate()->Set(String::NewSymbol("createColumnFamily"), - FunctionTemplate::New(CreateColumnFamily)->GetFunction()); - tpl->PrototypeTemplate()->Set(String::NewSymbol("writeBatch"), - FunctionTemplate::New(WriteBatch)->GetFunction()); - tpl->PrototypeTemplate()->Set(String::NewSymbol("compactRange"), - FunctionTemplate::New(CompactRange)->GetFunction()); - - constructor = Persistent::New(tpl->GetFunction()); - exports->Set(String::NewSymbol("DBWrapper"), constructor); -} - -Handle DBWrapper::Open(const Arguments& args) { - HandleScope scope; - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - - if (!(args[0]->IsString() && - (args[1]->IsUndefined() || args[1]->IsArray()))) { - return scope.Close(Boolean::New(false)); - } - - std::string db_file = *v8::String::Utf8Value(args[0]->ToString()); - - std::vector cfs = {ROCKSDB_NAMESPACE::kDefaultColumnFamilyName}; - - if (!args[1]->IsUndefined()) { - Handle array = Handle::Cast(args[1]); - for (uint i = 0; i < array->Length(); i++) { - if (!array->Get(i)->IsString()) { - return scope.Close(Boolean::New(false)); - } - - cfs.push_back(*v8::String::Utf8Value(array->Get(i)->ToString())); - } - } - - if (cfs.size() == 1) { - db_wrapper->status_ = ROCKSDB_NAMESPACE::DB::Open( - db_wrapper->options_, db_file, &db_wrapper->db_); - - return scope.Close(Boolean::New(db_wrapper->status_.ok())); - } - - std::vector families; - - for (std::vector::size_type i = 0; i < cfs.size(); i++) { - families.push_back(ROCKSDB_NAMESPACE::ColumnFamilyDescriptor( - cfs[i], ROCKSDB_NAMESPACE::ColumnFamilyOptions())); - } - - std::vector handles; - db_wrapper->status_ = ROCKSDB_NAMESPACE::DB::Open( - db_wrapper->options_, db_file, families, &handles, &db_wrapper->db_); - - if (!db_wrapper->status_.ok()) { - return scope.Close(Boolean::New(db_wrapper->status_.ok())); - } - - for (std::vector::size_type i = 0; i < handles.size(); i++) { - db_wrapper->columnFamilies_[cfs[i]] = handles[i]; - } - - return scope.Close(Boolean::New(true)); -} - - -Handle DBWrapper::New(const Arguments& args) { - HandleScope scope; - Handle to_return; - - if (args.IsConstructCall()) { - DBWrapper* db_wrapper = new DBWrapper(); - db_wrapper->Wrap(args.This()); - - return args.This(); - } - - const int argc = 0; - Local argv[0] = {}; - - return scope.Close(constructor->NewInstance(argc, argv)); -} - -Handle DBWrapper::Get(const Arguments& args) { - HandleScope scope; - - if (!(args[0]->IsString() && - (args[1]->IsUndefined() || args[1]->IsString()))) { - return scope.Close(Null()); - } - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - std::string key = *v8::String::Utf8Value(args[0]->ToString()); - std::string cf = *v8::String::Utf8Value(args[1]->ToString()); - std::string value; - - if (args[1]->IsUndefined()) { - db_wrapper->status_ = - db_wrapper->db_->Get(ROCKSDB_NAMESPACE::ReadOptions(), key, &value); - } else if (db_wrapper->HasFamilyNamed(cf, db_wrapper)) { - db_wrapper->status_ = - db_wrapper->db_->Get(ROCKSDB_NAMESPACE::ReadOptions(), - db_wrapper->columnFamilies_[cf], key, &value); - } else { - return scope.Close(Null()); - } - - Handle v = db_wrapper->status_.ok() ? - String::NewSymbol(value.c_str()) : Null(); - - return scope.Close(v); -} - -Handle DBWrapper::Put(const Arguments& args) { - HandleScope scope; - - if (!(args[0]->IsString() && args[1]->IsString() && - (args[2]->IsUndefined() || args[2]->IsString()))) { - return scope.Close(Boolean::New(false)); - } - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - std::string key = *v8::String::Utf8Value(args[0]->ToString()); - std::string value = *v8::String::Utf8Value(args[1]->ToString()); - std::string cf = *v8::String::Utf8Value(args[2]->ToString()); - - if (args[2]->IsUndefined()) { - db_wrapper->status_ = - db_wrapper->db_->Put(ROCKSDB_NAMESPACE::WriteOptions(), key, value); - } else if (db_wrapper->HasFamilyNamed(cf, db_wrapper)) { - db_wrapper->status_ = - db_wrapper->db_->Put(ROCKSDB_NAMESPACE::WriteOptions(), - db_wrapper->columnFamilies_[cf], key, value); - } else { - return scope.Close(Boolean::New(false)); - } - - - return scope.Close(Boolean::New(db_wrapper->status_.ok())); -} - -Handle DBWrapper::Delete(const Arguments& args) { - HandleScope scope; - - if (!args[0]->IsString()) { - return scope.Close(Boolean::New(false)); - } - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - std::string arg0 = *v8::String::Utf8Value(args[0]->ToString()); - std::string arg1 = *v8::String::Utf8Value(args[1]->ToString()); - - if (args[1]->IsUndefined()) { - db_wrapper->status_ = - db_wrapper->db_->Delete(ROCKSDB_NAMESPACE::WriteOptions(), arg0); - } else { - if (!db_wrapper->HasFamilyNamed(arg1, db_wrapper)) { - return scope.Close(Boolean::New(false)); - } - db_wrapper->status_ = - db_wrapper->db_->Delete(ROCKSDB_NAMESPACE::WriteOptions(), - db_wrapper->columnFamilies_[arg1], arg0); - } - - return scope.Close(Boolean::New(db_wrapper->status_.ok())); -} - -Handle DBWrapper::Dump(const Arguments& args) { - HandleScope scope; - std::unique_ptr iterator; - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - std::string arg0 = *v8::String::Utf8Value(args[0]->ToString()); - - if (args[0]->IsUndefined()) { - iterator.reset( - db_wrapper->db_->NewIterator(ROCKSDB_NAMESPACE::ReadOptions())); - } else { - if (!db_wrapper->HasFamilyNamed(arg0, db_wrapper)) { - return scope.Close(Boolean::New(false)); - } - - iterator.reset(db_wrapper->db_->NewIterator( - ROCKSDB_NAMESPACE::ReadOptions(), db_wrapper->columnFamilies_[arg0])); - } - - iterator->SeekToFirst(); - - while (iterator->Valid()) { - std::cout << "\""; - printWithBackSlashes(iterator->key().ToString()); - std::cout << "\" => \""; - printWithBackSlashes(iterator->value().ToString()); - std::cout << "\"\n"; - iterator->Next(); - } - - return scope.Close(Boolean::New(true)); -} - -Handle DBWrapper::CreateColumnFamily(const Arguments& args) { - HandleScope scope; - - if (!args[0]->IsString()) { - return scope.Close(Boolean::New(false)); - } - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - std::string cf_name = *v8::String::Utf8Value(args[0]->ToString()); - - if (db_wrapper->HasFamilyNamed(cf_name, db_wrapper)) { - return scope.Close(Boolean::New(false)); - } - - ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf; - db_wrapper->status_ = db_wrapper->db_->CreateColumnFamily( - ROCKSDB_NAMESPACE::ColumnFamilyOptions(), cf_name, &cf); - - if (!db_wrapper->status_.ok()) { - return scope.Close(Boolean::New(false)); - } - - db_wrapper->columnFamilies_[cf_name] = cf; - - return scope.Close(Boolean::New(true)); -} - -bool DBWrapper::AddToBatch(ROCKSDB_NAMESPACE::WriteBatch& batch, bool del, - Handle array) { - Handle put_pair; - for (uint i = 0; i < array->Length(); i++) { - if (del) { - if (!array->Get(i)->IsString()) { - return false; - } - - batch.Delete(*v8::String::Utf8Value(array->Get(i)->ToString())); - continue; - } - - if (!array->Get(i)->IsArray()) { - return false; - } - - put_pair = Handle::Cast(array->Get(i)); - - if (!put_pair->Get(0)->IsString() || !put_pair->Get(1)->IsString()) { - return false; - } - - batch.Put( - *v8::String::Utf8Value(put_pair->Get(0)->ToString()), - *v8::String::Utf8Value(put_pair->Get(1)->ToString())); - } - - return true; -} - -bool DBWrapper::AddToBatch(ROCKSDB_NAMESPACE::WriteBatch& batch, bool del, - Handle array, DBWrapper* db_wrapper, - std::string cf) { - Handle put_pair; - for (uint i = 0; i < array->Length(); i++) { - if (del) { - if (!array->Get(i)->IsString()) { - return false; - } - - batch.Delete( - db_wrapper->columnFamilies_[cf], - *v8::String::Utf8Value(array->Get(i)->ToString())); - continue; - } - - if (!array->Get(i)->IsArray()) { - return false; - } - - put_pair = Handle::Cast(array->Get(i)); - - if (!put_pair->Get(0)->IsString() || !put_pair->Get(1)->IsString()) { - return false; - } - - batch.Put( - db_wrapper->columnFamilies_[cf], - *v8::String::Utf8Value(put_pair->Get(0)->ToString()), - *v8::String::Utf8Value(put_pair->Get(1)->ToString())); - } - - return true; -} - -Handle DBWrapper::WriteBatch(const Arguments& args) { - HandleScope scope; - - if (!args[0]->IsArray()) { - return scope.Close(Boolean::New(false)); - } - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - Handle sub_batches = Handle::Cast(args[0]); - Local sub_batch; - ROCKSDB_NAMESPACE::WriteBatch batch; - bool well_formed; - - for (uint i = 0; i < sub_batches->Length(); i++) { - if (!sub_batches->Get(i)->IsObject()) { - return scope.Close(Boolean::New(false)); - } - sub_batch = sub_batches->Get(i)->ToObject(); - - if (sub_batch->Has(String::NewSymbol("column_family"))) { - if (!has_key_for_array(sub_batch, "put") && - !has_key_for_array(sub_batch, "delete")) { - return scope.Close(Boolean::New(false)); - } - - well_formed = db_wrapper->AddToBatch( - batch, false, - Handle::Cast(sub_batch->Get(String::NewSymbol("put"))), - db_wrapper, *v8::String::Utf8Value(sub_batch->Get( - String::NewSymbol("column_family")))); - - well_formed = db_wrapper->AddToBatch( - batch, true, - Handle::Cast(sub_batch->Get(String::NewSymbol("delete"))), - db_wrapper, *v8::String::Utf8Value(sub_batch->Get( - String::NewSymbol("column_family")))); - } else { - well_formed = db_wrapper->AddToBatch( - batch, false, - Handle::Cast(sub_batch->Get(String::NewSymbol("put")))); - well_formed = db_wrapper->AddToBatch( - batch, true, - Handle::Cast(sub_batch->Get(String::NewSymbol("delete")))); - - if (!well_formed) { - return scope.Close(Boolean::New(false)); - } - } - } - - db_wrapper->status_ = - db_wrapper->db_->Write(ROCKSDB_NAMESPACE::WriteOptions(), &batch); - - return scope.Close(Boolean::New(db_wrapper->status_.ok())); -} - -Handle DBWrapper::CompactRangeDefault(const Arguments& args) { - HandleScope scope; - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - ROCKSDB_NAMESPACE::Slice begin = *v8::String::Utf8Value(args[0]->ToString()); - ROCKSDB_NAMESPACE::Slice end = *v8::String::Utf8Value(args[1]->ToString()); - db_wrapper->status_ = db_wrapper->db_->CompactRange(&end, &begin); - - return scope.Close(Boolean::New(db_wrapper->status_.ok())); -} - -Handle DBWrapper::CompactColumnFamily(const Arguments& args) { - HandleScope scope; - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - ROCKSDB_NAMESPACE::Slice begin = *v8::String::Utf8Value(args[0]->ToString()); - ROCKSDB_NAMESPACE::Slice end = *v8::String::Utf8Value(args[1]->ToString()); - std::string cf = *v8::String::Utf8Value(args[2]->ToString()); - db_wrapper->status_ = db_wrapper->db_->CompactRange( - db_wrapper->columnFamilies_[cf], &begin, &end); - - return scope.Close(Boolean::New(db_wrapper->status_.ok())); -} - -Handle DBWrapper::CompactOptions(const Arguments& args) { - HandleScope scope; - - if (!args[2]->IsObject()) { - return scope.Close(Boolean::New(false)); - } - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - ROCKSDB_NAMESPACE::Slice begin = *v8::String::Utf8Value(args[0]->ToString()); - ROCKSDB_NAMESPACE::Slice end = *v8::String::Utf8Value(args[1]->ToString()); - Local options = args[2]->ToObject(); - int target_level = -1, target_path_id = 0; - - if (options->Has(String::NewSymbol("target_level")) && - options->Get(String::NewSymbol("target_level"))->IsInt32()) { - target_level = (int)(options->Get( - String::NewSymbol("target_level"))->ToInt32()->Value()); - - if (options->Has(String::NewSymbol("target_path_id")) || - options->Get(String::NewSymbol("target_path_id"))->IsInt32()) { - target_path_id = (int)(options->Get( - String::NewSymbol("target_path_id"))->ToInt32()->Value()); - } - } - - db_wrapper->status_ = db_wrapper->db_->CompactRange( - &begin, &end, true, target_level, target_path_id - ); - - return scope.Close(Boolean::New(db_wrapper->status_.ok())); -} - -Handle DBWrapper::CompactAll(const Arguments& args) { - HandleScope scope; - - if (!args[2]->IsObject() || !args[3]->IsString()) { - return scope.Close(Boolean::New(false)); - } - - DBWrapper* db_wrapper = ObjectWrap::Unwrap(args.This()); - ROCKSDB_NAMESPACE::Slice begin = *v8::String::Utf8Value(args[0]->ToString()); - ROCKSDB_NAMESPACE::Slice end = *v8::String::Utf8Value(args[1]->ToString()); - Local options = args[2]->ToObject(); - std::string cf = *v8::String::Utf8Value(args[3]->ToString()); - - int target_level = -1, target_path_id = 0; - - if (options->Has(String::NewSymbol("target_level")) && - options->Get(String::NewSymbol("target_level"))->IsInt32()) { - target_level = (int)(options->Get( - String::NewSymbol("target_level"))->ToInt32()->Value()); - - if (options->Has(String::NewSymbol("target_path_id")) || - options->Get(String::NewSymbol("target_path_id"))->IsInt32()) { - target_path_id = (int)(options->Get( - String::NewSymbol("target_path_id"))->ToInt32()->Value()); - } - } - - db_wrapper->status_ = db_wrapper->db_->CompactRange( - db_wrapper->columnFamilies_[cf], &begin, &end, true, target_level, - target_path_id); - - return scope.Close(Boolean::New(db_wrapper->status_.ok())); -} - -Handle DBWrapper::CompactRange(const Arguments& args) { - HandleScope scope; - - if (!args[0]->IsString() || !args[1]->IsString()) { - return scope.Close(Boolean::New(false)); - } - - switch(args.Length()) { - case 2: - return CompactRangeDefault(args); - case 3: - return args[2]->IsString() ? CompactColumnFamily(args) : - CompactOptions(args); - default: - return CompactAll(args); - } -} - -Handle DBWrapper::Close(const Arguments& args) { - HandleScope scope; - - delete ObjectWrap::Unwrap(args.This()); - - return scope.Close(Null()); -} diff --git a/tools/rdb/db_wrapper.h b/tools/rdb/db_wrapper.h deleted file mode 100644 index ece7dfefc..000000000 --- a/tools/rdb/db_wrapper.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -#ifndef DBWRAPPER_H -#define DBWRAPPER_H - -#include -#include - -#include "rocksdb/db.h" -#include "rocksdb/slice.h" -#include "rocksdb/options.h" - -// Used to encapsulate a particular instance of an opened database. -// -// This object should not be used directly in C++; it exists solely to provide -// a mapping from a JavaScript object to a C++ code that can use the RocksDB -// API. -class DBWrapper : public node::ObjectWrap { - public: - static void Init(Handle exports); - - private: - explicit DBWrapper(); - ~DBWrapper(); - - // Helper methods - static bool HasFamilyNamed(std::string& name, DBWrapper* db); - static bool AddToBatch(ROCKSDB_NAMESPACE::WriteBatch& batch, bool del, - Handle array); - static bool AddToBatch(ROCKSDB_NAMESPACE::WriteBatch& batch, bool del, - Handle array, DBWrapper* db_wrapper, - std::string cf); - static Handle CompactRangeDefault(const v8::Arguments& args); - static Handle CompactColumnFamily(const Arguments& args); - static Handle CompactOptions(const Arguments& args); - static Handle CompactAll(const Arguments& args); - - // C++ mappings of API methods - static Persistent constructor; - static Handle Open(const Arguments& args); - static Handle New(const Arguments& args); - static Handle Get(const Arguments& args); - static Handle Put(const Arguments& args); - static Handle Delete(const Arguments& args); - static Handle Dump(const Arguments& args); - static Handle WriteBatch(const Arguments& args); - static Handle CreateColumnFamily(const Arguments& args); - static Handle CompactRange(const Arguments& args); - static Handle Close(const Arguments& args); - - // Internal fields - ROCKSDB_NAMESPACE::Options options_; - ROCKSDB_NAMESPACE::Status status_; - ROCKSDB_NAMESPACE::DB* db_; - std::unordered_map - columnFamilies_; -}; - -#endif diff --git a/tools/rdb/rdb b/tools/rdb/rdb deleted file mode 100755 index 05da1158b..000000000 --- a/tools/rdb/rdb +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -node -e "RDB = require('./build/Release/rdb').DBWrapper; console.log('Loaded rocksdb in variable RDB'); repl = require('repl').start('> ');" diff --git a/tools/rdb/rdb.cc b/tools/rdb/rdb.cc deleted file mode 100644 index c1375bb62..000000000 --- a/tools/rdb/rdb.cc +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -#ifndef BUILDING_NODE_EXTENSION -#define BUILDING_NODE_EXTENSION -#endif - -#include -#include -#include "db/_wrapper.h" - -void InitAll(Handle exports) { - DBWrapper::Init(exports); -} - -NODE_MODULE(rdb, InitAll) diff --git a/tools/rdb/unit_test.js b/tools/rdb/unit_test.js deleted file mode 100644 index d01ae1df8..000000000 --- a/tools/rdb/unit_test.js +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -assert = require('assert') -RDB = require('./build/Release/rdb').DBWrapper -exec = require('child_process').exec -util = require('util') - -DB_NAME = '/tmp/rocksdbtest-' + process.getuid() - -a = RDB() -assert.equal(a.open(DB_NAME, ['b']), false) - -exec( - util.format( - "node -e \"RDB = require('./build/Release/rdb').DBWrapper; \ - a = RDB('%s'); a.createColumnFamily('b')\"", - DB_NAME - ).exitCode, null -) - - -exec( - util.format( - "node -e \"RDB = require('./build/Release/rdb').DBWrapper; \ - a = RDB('%s', ['b'])\"", - DB_NAME - ).exitCode, null -) - -exec('rm -rf ' + DB_NAME) - -a = RDB() -assert.equal(a.open(DB_NAME, ['a']), false) -assert(a.open(DB_NAME), true) -assert(a.createColumnFamily('temp')) - -b = RDB() -assert.equal(b.open(DB_NAME), false) - -exec('rm -rf ' + DB_NAME) - -DB_NAME += 'b' - -a = RDB() -assert(a.open(DB_NAME)) -assert.equal(a.constructor.name, 'DBWrapper') -assert.equal(a.createColumnFamily(), false) -assert.equal(a.createColumnFamily(1), false) -assert.equal(a.createColumnFamily(['']), false) -assert(a.createColumnFamily('b')) -assert.equal(a.createColumnFamily('b'), false) - -// Get and Put -assert.equal(a.get(1), null) -assert.equal(a.get(['a']), null) -assert.equal(a.get('a', 1), null) -assert.equal(a.get(1, 'a'), null) -assert.equal(a.get(1, 1), null) - -assert.equal(a.put(1), false) -assert.equal(a.put(['a']), false) -assert.equal(a.put('a', 1), false) -assert.equal(a.put(1, 'a'), false) -assert.equal(a.put(1, 1), false) -assert.equal(a.put('a', 'a', 1), false) -assert.equal(a.put('a', 1, 'a'), false) -assert.equal(a.put(1, 'a', 'a'), false) -assert.equal(a.put('a', 1, 1), false) -assert.equal(a.put(1, 'a', 1), false) -assert.equal(a.put(1, 1, 'a'), false) -assert.equal(a.put(1, 1, 1), false) - - -assert.equal(a.get(), null) -assert.equal(a.get('a'), null) -assert.equal(a.get('a', 'c'), null) -assert.equal(a.put(), false) -assert.equal(a.put('a'), false) -assert.equal(a.get('a', 'b', 'c'), null) - -assert(a.put('a', 'axe')) -assert(a.put('a', 'first')) -assert.equal(a.get('a'), 'first') -assert.equal(a.get('a', 'b'), null) -assert.equal(a.get('a', 'c'), null) - -assert(a.put('a', 'apple', 'b')) -assert.equal(a.get('a', 'b'), 'apple') -assert.equal(a.get('a'), 'first') -assert(a.put('b', 'butter', 'b'), 'butter') -assert(a.put('b', 'banana', 'b')) -assert.equal(a.get('b', 'b'), 'banana') -assert.equal(a.get('b'), null) -assert.equal(a.get('b', 'c'), null) - -// Delete -assert.equal(a.delete(1), false) -assert.equal(a.delete('a', 1), false) -assert.equal(a.delete(1, 'a'), false) -assert.equal(a.delete(1, 1), false) - -assert.equal(a.delete('b'), true) -assert(a.delete('a')) -assert.equal(a.get('a'), null) -assert.equal(a.get('a', 'b'), 'apple') -assert.equal(a.delete('c', 'c'), false) -assert.equal(a.delete('c', 'b'), true) -assert(a.delete('b', 'b')) -assert.equal(a.get('b', 'b'), null) - -// Dump -console.log("MARKER 1") -assert(a.dump()) -console.log("Should be no output between 'MARKER 1' and here\n") -console.log('Next line should be "a" => "apple"') -assert(a.dump('b')) - -console.log("\nMARKER 2") -assert.equal(a.dump('c'), false) -console.log("Should be no output between 'MARKER 2' and here\n") - -// WriteBatch - - -// Clean up test database -exec('rm -rf ' + DB_NAME)