diff --git a/hbase-native-client/core/BUCK b/hbase-native-client/core/BUCK index e9fc716..cd38c15 100644 --- a/hbase-native-client/core/BUCK +++ b/hbase-native-client/core/BUCK @@ -38,6 +38,7 @@ cxx_library( "get.h", "mutation.h", "put.h", + "delete.h", "scan.h", "result.h", "request-converter.h", @@ -68,6 +69,7 @@ cxx_library( "get.cc", "mutation.cc", "put.cc", + "delete.cc", "scan.cc", "raw-async-table.cc", "result.cc", diff --git a/hbase-native-client/core/client-test.cc b/hbase-native-client/core/client-test.cc index 1c6ec4a..c7f9328 100644 --- a/hbase-native-client/core/client-test.cc +++ b/hbase-native-client/core/client-test.cc @@ -22,6 +22,7 @@ #include "core/cell.h" #include "core/client.h" #include "core/configuration.h" +#include "core/delete.h" #include "core/get.h" #include "core/hbase-configuration-loader.h" #include "core/put.h" @@ -144,6 +145,12 @@ TEST_F(ClientTest, PutGet) { EXPECT_EQ("value1", *(result->Value("d", "1"))); EXPECT_EQ("value for extra", *(result->Value("d", "extra"))); + // Delete the row and verify that subsequent Get returns nothing + hbase::Delete del(row); + table->Delete(del); + result = table->Get(get); + ASSERT_TRUE(result->IsEmpty()) << "Result should be empty."; + table->Close(); client.Close(); } diff --git a/hbase-native-client/core/raw-async-table.cc b/hbase-native-client/core/raw-async-table.cc index 9e0d4a3..240ff36 100644 --- a/hbase-native-client/core/raw-async-table.cc +++ b/hbase-native-client/core/raw-async-table.cc @@ -91,6 +91,21 @@ Future RawAsyncTable::Put(const hbase::Put& put) { return caller->Call().then([caller](const auto r) { return r; }); } +Future RawAsyncTable::Delete(const hbase::Delete& del) { + auto caller = + CreateCallerBuilder(del.row(), connection_conf_->write_rpc_timeout()) + ->action([=, &del](std::shared_ptr controller, + std::shared_ptr loc, + std::shared_ptr rpc_client) -> folly::Future { + return Call( + rpc_client, controller, loc, del, &hbase::RequestConverter::DelToMutateRequest, + [](const Response& r) -> Unit { return folly::unit; }); + }) + ->Build(); + + return caller->Call().then([caller](const auto r) { return r; }); +} + Future>>> RawAsyncTable::Get( const std::vector& gets) { return this->Batch(gets); diff --git a/hbase-native-client/core/raw-async-table.h b/hbase-native-client/core/raw-async-table.h index e26d46e..5e86876 100644 --- a/hbase-native-client/core/raw-async-table.h +++ b/hbase-native-client/core/raw-async-table.h @@ -29,6 +29,7 @@ #include "core/async-rpc-retrying-caller-factory.h" #include "core/async-rpc-retrying-caller.h" #include "core/connection-configuration.h" +#include "core/delete.h" #include "core/get.h" #include "core/put.h" #include "core/result.h" @@ -58,6 +59,7 @@ class RawAsyncTable { Future> Get(const hbase::Get& get); Future Put(const hbase::Put& put); + Future Delete(const hbase::Delete& del); void Close() {} Future>>> Get(const std::vector& gets); diff --git a/hbase-native-client/core/request-converter.cc b/hbase-native-client/core/request-converter.cc index c90e1ab..faccb08 100644 --- a/hbase-native-client/core/request-converter.cc +++ b/hbase-native-client/core/request-converter.cc @@ -219,4 +219,17 @@ std::unique_ptr RequestConverter::ToMutateRequest(const Put &put, VLOG(3) << "Req is " << pb_req->req_msg()->ShortDebugString(); return pb_req; } + +std::unique_ptr RequestConverter::DelToMutateRequest(const Delete &del, + const std::string ®ion_name) { + auto pb_req = Request::mutate(); + auto pb_msg = std::static_pointer_cast(pb_req->req_msg()); + RequestConverter::SetRegion(region_name, pb_msg->mutable_region()); + + pb_msg->set_allocated_mutation( + ToMutation(MutationType::MutationProto_MutationType_DELETE, del, -1).release()); + + VLOG(3) << "Req is " << pb_req->req_msg()->ShortDebugString(); + return pb_req; +} } /* namespace hbase */ diff --git a/hbase-native-client/core/request-converter.h b/hbase-native-client/core/request-converter.h index 6861604..4753f5f 100644 --- a/hbase-native-client/core/request-converter.h +++ b/hbase-native-client/core/request-converter.h @@ -25,6 +25,7 @@ #include "connection/request.h" #include "core/action.h" #include "core/cell.h" +#include "core/delete.h" #include "core/get.h" #include "core/mutation.h" #include "core/put.h" @@ -71,6 +72,8 @@ class RequestConverter { static std::unique_ptr ToMultiRequest(const ActionsByRegion ®ion_requests); + static std::unique_ptr DelToMutateRequest(const Delete &del,const std::string ®ion_name); + static std::unique_ptr ToMutateRequest(const Put &put, const std::string ®ion_name); static std::unique_ptr ToMutation(const MutationType type, diff --git a/hbase-native-client/core/table.cc b/hbase-native-client/core/table.cc index a2f31d9..dd26adf 100644 --- a/hbase-native-client/core/table.cc +++ b/hbase-native-client/core/table.cc @@ -57,6 +57,11 @@ void Table::Put(const hbase::Put &put) { future.get(operation_timeout()); } +void Table::Delete(const hbase::Delete &del) { + auto future = async_table_->Delete(del); + future.get(operation_timeout()); +} + milliseconds Table::operation_timeout() const { return TimeUtil::ToMillis(async_connection_->connection_conf()->operation_timeout()); } diff --git a/hbase-native-client/core/table.h b/hbase-native-client/core/table.h index 142baae..a6d8806 100644 --- a/hbase-native-client/core/table.h +++ b/hbase-native-client/core/table.h @@ -62,6 +62,12 @@ class Table { */ void Put(const hbase::Put &put); + /** + * @brief - Deletes some data in the table. + * @param - del Delete object to perform HBase Delete operation. + */ + void Delete(const hbase::Delete &del); + // TODO: Batch Puts /** diff --git a/hbase-native-client/core/delete.h b/hbase-native-client/core/delete.h new file mode 100644 index 0000000..419e9e0 --- /dev/null +++ b/hbase-native-client/core/delete.h @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "core/cell.h" +#include "core/mutation.h" + +namespace hbase { + +class Delete : public Mutation { + public: + /** + * Constructors + */ + explicit Delete(const std::string& row) : Mutation(row) {} + Delete(const std::string& row, int64_t timestamp) : Mutation(row, timestamp) {} + Delete(const Delete& cdelete) : Mutation(cdelete) {} + Delete& operator=(const Delete& cdelete) { + Mutation::operator=(cdelete); + return *this; + } + + ~Delete() = default; + + /** + * @brief Add the specified column to this Delete operation. + * @param family family name + * @param qualifier column qualifier + */ + Delete& AddColumn(const std::string& family, const std::string& qualifier); + + /** + * @brief Add the specified column to this Delete operation. + * @param family family name + * @param qualifier column qualifier + * @param timestamp version timestamp + */ + Delete& AddColumn(const std::string& family, const std::string& qualifier, int64_t timestamp); + + /** + * Advanced use only. + * Add an existing delete marker to this Delete object. + */ + Delete& Add(std::unique_ptr cell); +}; + +} // namespace hbase diff --git a/hbase-native-client/core/delete.cc b/hbase-native-client/core/delete.cc new file mode 100644 index 0000000..d36b20b --- /dev/null +++ b/hbase-native-client/core/delete.cc @@ -0,0 +1,67 @@ + + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "core/delete.h" +#include +#include +#include +#include +#include + +namespace hbase { + +/** + * @brief Add the specified column to this Delete operation. + * @param family family name + * @param qualifier column qualifier + */ +Delete& Delete::AddColumn(const std::string& family, const std::string& qualifier) { + return AddColumn(family, qualifier, timestamp_); +} + +/** + * @brief Add the specified column to this Delete operation. + * @param family family name + * @param qualifier column qualifier + * @param timestamp version timestamp + */ +Delete& Delete::AddColumn(const std::string& family, const std::string& qualifier, + int64_t timestamp) { + if (timestamp < 0) { + throw std::runtime_error("Timestamp cannot be negative. ts=" + + folly::to(timestamp)); + } + + SetTimeStamp(timestamp); + return Add(std::make_unique(row_, family, qualifier, timestamp, nullptr, + hbase::CellType::DELETE)); +} + +Delete& Delete::Add(std::unique_ptr cell) { + if (cell->Row() != row_) { + throw std::runtime_error("The row in " + cell->DebugString() + + " doesn't match the original one " + row_); + } + + family_map_[cell->Family()].push_back(std::move(cell)); + return *this; +} +} // namespace hbase