Repository: hbase
Updated Branches:
  refs/heads/HBASE-14850 d308e0d35 -> c561d5728


HBASE-17226 [C++] Filter and Query classes


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/c561d572
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/c561d572
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/c561d572

Branch: refs/heads/HBASE-14850
Commit: c561d5728d78aed42bd99ea4e46fc79a2a6b6eae
Parents: d308e0d
Author: Enis Soztutar <e...@apache.org>
Authored: Fri Feb 24 14:18:18 2017 -0800
Committer: Enis Soztutar <e...@apache.org>
Committed: Fri Feb 24 14:18:18 2017 -0800

----------------------------------------------------------------------
 hbase-native-client/core/BUCK                 |  12 +
 hbase-native-client/core/filter-test.cc       | 136 ++++++
 hbase-native-client/core/filter.h             | 481 +++++++++++++++++++++
 hbase-native-client/core/get.h                |   3 +-
 hbase-native-client/core/query.h              |  41 ++
 hbase-native-client/core/request_converter.cc |   8 +
 hbase-native-client/core/scan.h               |   2 +-
 7 files changed, 681 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/c561d572/hbase-native-client/core/BUCK
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/BUCK b/hbase-native-client/core/BUCK
index d8d15a9..ce0c733 100644
--- a/hbase-native-client/core/BUCK
+++ b/hbase-native-client/core/BUCK
@@ -22,6 +22,8 @@ cxx_library(
         "client.h",
         "cell.h",
         "hbase_macros.h",
+        "filter.h",
+        "query.h",
         "keyvalue-codec.h",
         "region-location.h",
         "location-cache.h",
@@ -78,6 +80,16 @@ cxx_test(
     deps=[":core",],
     run_test_separately=True,)
 cxx_test(
+    name="filter-test",
+    srcs=["filter-test.cc",],
+    deps=[
+        ":core",
+        "//if:if",
+        "//serde:serde",
+        "//test-util:test-util",
+    ],
+    run_test_separately=True,)
+cxx_test(
     name="get-test",
     srcs=["get-test.cc",],
     deps=[":core",],

http://git-wip-us.apache.org/repos/asf/hbase/blob/c561d572/hbase-native-client/core/filter-test.cc
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/filter-test.cc 
b/hbase-native-client/core/filter-test.cc
new file mode 100644
index 0000000..ff683b6
--- /dev/null
+++ b/hbase-native-client/core/filter-test.cc
@@ -0,0 +1,136 @@
+/*
+ * 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 <gtest/gtest.h>
+#include "core/client.h"
+#include "core/configuration.h"
+#include "core/get.h"
+#include "core/result.h"
+#include "core/table.h"
+#include "if/Comparator.pb.h"
+#include "if/HBase.pb.h"
+#include "serde/table-name.h"
+#include "test-util/test-util.h"
+
+using hbase::Configuration;
+using hbase::Get;
+using hbase::FilterFactory;
+using hbase::Table;
+using hbase::TestUtil;
+using hbase::pb::CompareType;
+using hbase::ComparatorFactory;
+using hbase::Comparator;
+
+class FilterTest : public ::testing::Test {
+ protected:
+  static void SetUpTestCase() { test_util_ = std::make_unique<TestUtil>(); }
+
+  static void TearDownTestCase() { test_util_.release(); }
+
+  virtual void SetUp() {}
+  virtual void TearDown() {}
+
+  static std::unique_ptr<TestUtil> test_util_;
+};
+
+std::unique_ptr<TestUtil> FilterTest::test_util_ = nullptr;
+
+TEST_F(FilterTest, GetWithColumnPrefixFilter) {
+  // write row1 with 3 columns (column_1, column_2, and foo_column)
+  FilterTest::test_util_->RunShellCmd(
+      "create 't', 'd'; put 't', 'row1', 'd:column_1', 'value1'; put 't', 
'row1', 'd:column_2', "
+      "'value2'; put 't', 'row1', 'd:foo_column', 'value3'");
+
+  // Create TableName and Row to be fetched from HBase
+  auto tn = folly::to<hbase::pb::TableName>("t");
+  auto row = "row1";
+
+  // Gets to be performed on above HBase Table
+  Get get_all(row);  // expected to return all 3 columns
+  Get get_one(row);  // expected to return 1 column
+  Get get_two(row);  // expected to return 2 column
+
+  get_one.SetFilter(FilterFactory::ColumnPrefixFilter("foo_"));
+  get_two.SetFilter(FilterFactory::ColumnPrefixFilter("column_"));
+
+  // Create a client
+  hbase::Client client(Configuration{});
+
+  // Get connection to HBase Table
+  auto table = client.Table(tn);
+  ASSERT_TRUE(table) << "Unable to get connection to Table.";
+
+  // Perform the Get
+  auto result_all = table->Get(get_all);
+  auto result_one = table->Get(get_one);
+  auto result_two = table->Get(get_two);
+
+  table->Close();
+  client.Close();
+
+  // Test the values
+  ASSERT_TRUE(!result_one->IsEmpty()) << "Result shouldn't be empty.";
+  ASSERT_TRUE(!result_two->IsEmpty()) << "Result shouldn't be empty.";
+  ASSERT_TRUE(!result_all->IsEmpty()) << "Result shouldn't be empty.";
+  EXPECT_EQ(row, result_one->Row());
+  EXPECT_EQ(row, result_two->Row());
+  EXPECT_EQ(row, result_all->Row());
+  EXPECT_EQ(1, result_one->Size());
+  EXPECT_EQ(2, result_two->Size());
+  EXPECT_EQ(3, result_all->Size());
+  EXPECT_EQ("value3", *(result_one->Value("d", "foo_column")));
+  EXPECT_EQ("value1", *(result_two->Value("d", "column_1")));
+  EXPECT_EQ("value2", *(result_two->Value("d", "column_2")));
+}
+
+TEST_F(FilterTest, GetWithQualifierFilter) {
+  // write row1 with 3 columns (a,b,c)
+  FilterTest::test_util_->RunShellCmd(
+      "create 't1', 'd'; put 't1', 'row1', 'd:a', 'value1'; put 't1', 'row1', 
'd:b', "
+      "'value2'; put 't1', 'row1', 'd:c', 'value3'");
+
+  // Create TableName and Row to be fetched from HBase
+  auto tn = folly::to<hbase::pb::TableName>("t1");
+  auto row = "row1";
+
+  // Gets to be performed on above HBase Table
+  Get get(row);
+  get.SetFilter(FilterFactory::QualifierFilter(CompareType::GREATER_OR_EQUAL,
+                                               
*ComparatorFactory::BinaryComparator("b")));
+
+  // Create a client
+  hbase::Client client(Configuration{});
+
+  // Get connection to HBase Table
+  auto table = client.Table(tn);
+  ASSERT_TRUE(table) << "Unable to get connection to Table.";
+
+  // Perform the Get
+  auto result = table->Get(get);
+
+  table->Close();
+  client.Close();
+
+  // Test the values
+  ASSERT_TRUE(!result->IsEmpty()) << "Result shouldn't be empty.";
+  EXPECT_EQ(row, result->Row());
+  EXPECT_EQ(2, result->Size());
+  EXPECT_EQ("value2", *(result->Value("d", "b")));
+  EXPECT_EQ("value3", *(result->Value("d", "c")));
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/c561d572/hbase-native-client/core/filter.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/filter.h 
b/hbase-native-client/core/filter.h
new file mode 100644
index 0000000..b5b7133
--- /dev/null
+++ b/hbase-native-client/core/filter.h
@@ -0,0 +1,481 @@
+/*
+ * 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 <memory>
+#include <string>
+#include <utility>
+#include <set>
+#include <vector>
+
+#include "if/Comparator.pb.h"
+#include "if/Filter.pb.h"
+#include "if/HBase.pb.h"
+
+using google::protobuf::Message;
+
+namespace hbase {
+
+/**
+ * In C++ Client, Filter is a thin wrapper for calling filters defined as a 
Java class. The actual
+ * filtering logic is not implemented here, but this class provides a 
mechanism to call
+ * pre-existing Filter classes (like KeyOnlyFilter, SingleColumnValueFilter, 
etc) with your Get or
+ * Scan RPCs. This class can also be used to call custom Filters defined as a 
Java class, or
+ * pre-existing Filters not defined below. Some of the interfaces depends on 
protobuf classes
+ * defined in HBase.proto, Filter.proto and Comparator.proto.
+ *
+ * Consult the Java class docs for learning about the various filters and how 
they work (and filter
+ * arguments).
+ *
+ * Pre-existing Filters can be used like this:
+ *
+ * Get get(row);
+ * get.SetFilter(FilterFactory::ColumnPrefixFilter("foo_"));
+ *
+ * Custom filters can be invoked like this:
+ * Get get(row);
+ * std::string filter_java_class_name = "foo.bar.baz";
+ * auto filter_data = std::make_unique<pb::MyFilter>();
+ * filter_data->set_foo(foo);
+ * get.SetFilter(std::make_unique<Filter>(filter_java_class_name, 
filter_data));
+ *
+ */
+class Filter {
+ public:
+  Filter(std::string java_class_name, std::unique_ptr<Message> data)
+      : java_class_name_(java_class_name), data_(std::move(data)) {}
+  virtual ~Filter() {}
+
+  const std::string java_class_name() const { return java_class_name_; }
+
+  const Message& data() const { return *data_; }
+  /**
+   * Serialize the filter data to the given buffer. Does protobuf encoding by 
default.
+   * Can be overriden if Filter does not use protobuf.
+   */
+  virtual void Serialize(std::string* buf) const {
+    if (data_ != nullptr) {
+      data_->SerializeToString(buf);
+    }
+  }
+
+  /** Internal method */
+  static std::unique_ptr<pb::Filter> ToProto(const Filter& filter) {
+    auto pb_filter = std::make_unique<pb::Filter>();
+    pb_filter->set_name(filter.java_class_name());
+    filter.Serialize(pb_filter->mutable_serialized_filter());
+    return std::move(pb_filter);
+  }
+
+ private:
+  std::unique_ptr<Message> data_;
+  std::string java_class_name_;
+};
+
+/**
+ * Comparator for filters. See ByteArrayComparable documentation in Java.
+ */
+class Comparator {
+ public:
+  Comparator(std::string java_class_name, std::unique_ptr<Message> data)
+      : java_class_name_(java_class_name), data_(std::move(data)) {}
+  virtual ~Comparator() {}
+
+  const std::string java_class_name() const { return java_class_name_; }
+
+  /**
+   * Serialize the Comparator data to the given buffer. Does protobuf encoding 
by default.
+   * Can be overriden if Comparator does not use protobuf.
+   */
+  virtual void Serialize(std::string* buf) const {
+    if (data_ != nullptr) {
+      data_->SerializeToString(buf);
+    }
+  }
+
+  /** Internal method */
+  static std::unique_ptr<pb::Comparator> ToProto(const Comparator& comparator) 
{
+    auto pb_comparator = std::make_unique<pb::Comparator>();
+    pb_comparator->set_name(comparator.java_class_name());
+    comparator.Serialize(pb_comparator->mutable_serialized_comparator());
+    return std::move(pb_comparator);
+  }
+
+ private:
+  std::unique_ptr<Message> data_;
+  std::string java_class_name_;
+};
+
+/**
+ * Used in row range filters
+ */
+struct RowRange {
+  std::string start_row;
+  bool start_row_inclusive;
+  std::string stop_row;
+  bool stop_row_inclusive;
+};
+
+/**
+ * Factory for creating pre-defined filters.
+ */
+class FilterFactory {
+ public:
+  static std::unique_ptr<Filter> ColumnCountGetFilter(uint32_t limit) noexcept 
{
+    auto data = std::make_unique<pb::ColumnCountGetFilter>();
+    data->set_limit(limit);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.ColumnCountGetFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> ColumnPaginationFilter(uint32_t limit, 
uint32_t offset) noexcept {
+    auto data = std::make_unique<pb::ColumnPaginationFilter>();
+    data->set_limit(limit);
+    data->set_offset(offset);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.ColumnPaginationFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> ColumnPaginationFilter(uint32_t limit,
+                                                        const std::string& 
column_offset) noexcept {
+    auto data = std::make_unique<pb::ColumnPaginationFilter>();
+    data->set_limit(limit);
+    data->set_column_offset(column_offset);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.ColumnPaginationFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> ColumnPrefixFilter(const std::string& prefix) 
noexcept {
+    auto data = std::make_unique<pb::ColumnPrefixFilter>();
+    data->set_prefix(prefix);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.ColumnPrefixFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> ColumnRangeFilter(const std::string& 
min_column,
+                                                   bool min_column_inclusive,
+                                                   const std::string& 
max_column,
+                                                   bool max_column_inclusive) 
noexcept {
+    auto data = std::make_unique<pb::ColumnRangeFilter>();
+    data->set_min_column(min_column);
+    data->set_min_column_inclusive(min_column_inclusive);
+    data->set_max_column(max_column);
+    data->set_max_column_inclusive(max_column_inclusive);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.ColumnRangeFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<pb::CompareFilter> CompareFilter(pb::CompareType 
compare_op,
+                                                          const Comparator& 
comparator) noexcept {
+    auto data = std::make_unique<pb::CompareFilter>();
+    data->set_compare_op(compare_op);
+    data->set_allocated_comparator(Comparator::ToProto(comparator).release());
+    return std::move(data);
+  }
+
+  /**
+    * Build a dependent column filter with value checking
+    * dependent column varies will be compared using the supplied
+    * compareOp and comparator, for usage of which
+    * refer to {@link CompareFilter}
+    *
+    * @param family dependent column family
+    * @param qualifier dependent column qualifier
+    * @param drop_dependent_column whether the column should be discarded after
+    * @param compare_op comparison op
+    * @param comparator comparator
+    */
+  static std::unique_ptr<Filter> DependentColumnFilter(const std::string& 
family,
+                                                       const std::string& 
qualifier,
+                                                       bool 
drop_dependent_column,
+                                                       pb::CompareType 
compare_op,
+                                                       const Comparator& 
comparator) noexcept {
+    auto data = std::make_unique<pb::DependentColumnFilter>();
+    data->set_column_family(family);
+    data->set_column_qualifier(qualifier);
+    data->set_drop_dependent_column(drop_dependent_column);
+    data->set_allocated_compare_filter(CompareFilter(compare_op, 
comparator).release());
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.DependentColumnFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> FamilyFilter(pb::CompareType compare_op,
+                                              const Comparator& comparator) 
noexcept {
+    auto data = std::make_unique<pb::FamilyFilter>();
+    data->set_allocated_compare_filter(CompareFilter(compare_op, 
comparator).release());
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.FamilyFilter", 
std::move(data));
+  }
+
+  static std::unique_ptr<Filter> FilterAllFilter() noexcept {
+    auto data = std::make_unique<pb::FilterAllFilter>();
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.FilterAllFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> FilterList(
+      pb::FilterList_Operator op, const std::vector<std::unique_ptr<Filter>>& 
filters) noexcept {
+    auto data = std::make_unique<pb::FilterList>();
+    data->set_operator_(op);
+    for (auto const& f : filters) {
+      data->mutable_filters()->AddAllocated(Filter::ToProto(*f).release());
+    }
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.FilterList", 
std::move(data));
+  }
+
+  static std::unique_ptr<Filter> FirstKeyOnlyFilter() noexcept {
+    auto data = std::make_unique<pb::FirstKeyOnlyFilter>();
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> FirstKeyValueMatchingQualifiersFilter(
+      const std::set<std::string>& qualifiers) noexcept {
+    auto data = std::make_unique<pb::FirstKeyValueMatchingQualifiersFilter>();
+    for (auto q : qualifiers) {
+      data->add_qualifiers(q);
+    }
+    return std::make_unique<Filter>(
+        
"org.apache.hadoop.hbase.filter.FirstKeyValueMatchingQualifiersFilter", 
std::move(data));
+  }
+
+  static std::unique_ptr<Filter> FuzzyRowFilter(
+      const std::vector<std::pair<std::string, std::string>>& fuzzy_keys_data) 
noexcept {
+    auto data = std::make_unique<pb::FuzzyRowFilter>();
+    for (auto q : fuzzy_keys_data) {
+      auto p = data->add_fuzzy_keys_data();
+      p->set_first(q.first);
+      p->set_second(q.second);
+    }
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.FuzzyRowFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> InclusiveStopFilter(const std::string& 
stop_row_key) noexcept {
+    auto data = std::make_unique<pb::InclusiveStopFilter>();
+    data->set_stop_row_key(stop_row_key);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.InclusiveStopFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> KeyOnlyFilter(bool len_as_val) noexcept {
+    auto data = std::make_unique<pb::KeyOnlyFilter>();
+    data->set_len_as_val(len_as_val);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.KeyOnlyFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> MultipleColumnPrefixFilter(
+      const std::vector<std::string>& sorted_prefixes) noexcept {
+    auto data = std::make_unique<pb::MultipleColumnPrefixFilter>();
+    for (auto p : sorted_prefixes) {
+      data->add_sorted_prefixes(p);
+    }
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.MultipleColumnPrefixFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> MultiRowRangeFilter(
+      const std::vector<RowRange>& row_ranges) noexcept {
+    auto data = std::make_unique<pb::MultiRowRangeFilter>();
+    for (auto r : row_ranges) {
+      auto range = data->add_row_range_list();
+      range->set_start_row(r.start_row);
+      range->set_start_row_inclusive(r.start_row_inclusive);
+      range->set_stop_row(r.stop_row);
+      range->set_stop_row_inclusive(r.stop_row_inclusive);
+    }
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.MultiRowRangeFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> PageFilter(uint64_t page_size) noexcept {
+    auto data = std::make_unique<pb::PageFilter>();
+    data->set_page_size(page_size);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.PageFilter", 
std::move(data));
+  }
+
+  static std::unique_ptr<Filter> PrefixFilter(const std::string& prefix) 
noexcept {
+    auto data = std::make_unique<pb::PrefixFilter>();
+    data->set_prefix(prefix);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.PrefixFilter", 
std::move(data));
+  }
+
+  static std::unique_ptr<Filter> QualifierFilter(pb::CompareType compare_op,
+                                                 const Comparator& comparator) 
noexcept {
+    auto data = std::make_unique<pb::QualifierFilter>();
+    data->set_allocated_compare_filter(CompareFilter(compare_op, 
comparator).release());
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.QualifierFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> RandomRowFilter(float chance) noexcept {
+    auto data = std::make_unique<pb::RandomRowFilter>();
+    data->set_chance(chance);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.RandomRowFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> RowFilter(pb::CompareType compare_op,
+                                           const Comparator& comparator) 
noexcept {
+    auto data = std::make_unique<pb::RowFilter>();
+    data->set_allocated_compare_filter(CompareFilter(compare_op, 
comparator).release());
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.RowFilter", 
std::move(data));
+  }
+
+  static std::unique_ptr<Filter> SingleColumnValueExcludeFilter(
+      const std::string& family, const std::string& qualifier, bool 
filter_if_missing,
+      bool latest_version_only, pb::CompareType compare_op, const Comparator& 
comparator) noexcept {
+    auto data = std::make_unique<pb::SingleColumnValueExcludeFilter>();
+    auto f = SingleColumnValueFilterProto(family, qualifier, 
filter_if_missing, latest_version_only,
+                                          compare_op, comparator);
+    data->set_allocated_single_column_value_filter(f.release());
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<pb::SingleColumnValueFilter> 
SingleColumnValueFilterProto(
+      const std::string& family, const std::string& qualifier, bool 
filter_if_missing,
+      bool latest_version_only, pb::CompareType compare_op, const Comparator& 
comparator) noexcept {
+    auto data = std::make_unique<pb::SingleColumnValueFilter>();
+    data->set_column_family(family);
+    data->set_column_qualifier(qualifier);
+    data->set_compare_op(compare_op);
+    data->set_filter_if_missing(filter_if_missing);
+    data->set_latest_version_only(latest_version_only);
+    data->set_allocated_comparator(Comparator::ToProto(comparator).release());
+    return data;
+  }
+
+  static std::unique_ptr<Filter> SingleColumnValueFilter(
+      const std::string& family, const std::string& qualifier, bool 
filter_if_missing,
+      bool latest_version_only, pb::CompareType compare_op, const Comparator& 
comparator) noexcept {
+    auto data = SingleColumnValueFilterProto(family, qualifier, 
filter_if_missing,
+                                             latest_version_only, compare_op, 
comparator);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.SingleColumnValueFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> SkipFilter(const Filter& filter) noexcept {
+    auto data = std::make_unique<pb::SkipFilter>();
+    data->set_allocated_filter(Filter::ToProto(filter).release());
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.SkipFilter", 
std::move(data));
+  }
+
+  static std::unique_ptr<Filter> TimestampsFilter(std::vector<uint64_t> 
timestamps,
+                                                  bool can_hint) noexcept {
+    auto data = std::make_unique<pb::TimestampsFilter>();
+    for (auto t : timestamps) {
+      data->add_timestamps(t);
+    }
+    data->set_can_hint(can_hint);
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.TimestampsFilter",
+                                    std::move(data));
+  }
+
+  static std::unique_ptr<Filter> ValueFilter(pb::CompareType compare_op,
+                                             const Comparator& comparator) 
noexcept {
+    auto data = std::make_unique<pb::ValueFilter>();
+    data->set_allocated_compare_filter(CompareFilter(compare_op, 
comparator).release());
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.ValueFilter", 
std::move(data));
+  }
+
+  static std::unique_ptr<Filter> WhileMatchFilter(const Filter& filter) 
noexcept {
+    auto data = std::make_unique<pb::WhileMatchFilter>();
+    data->set_allocated_filter(Filter::ToProto(filter).release());
+    return 
std::make_unique<Filter>("org.apache.hadoop.hbase.filter.WhileMatchFilter",
+                                    std::move(data));
+  }
+};
+
+/**
+ * Factory for creating pre-defined Comparators.
+ */
+class ComparatorFactory {
+ public:
+  static std::unique_ptr<pb::ByteArrayComparable> ByteArrayComparable(
+      const std::string& value) noexcept {
+    auto data = std::make_unique<pb::ByteArrayComparable>();
+    data->set_value(value);
+    return std::move(data);
+  }
+
+  static std::unique_ptr<Comparator> BinaryComparator(const std::string& 
value) noexcept {
+    auto data = std::make_unique<pb::BinaryComparator>();
+    data->set_allocated_comparable(ByteArrayComparable(value).release());
+    return 
std::make_unique<Comparator>("org.apache.hadoop.hbase.filter.BinaryComparator",
+                                        std::move(data));
+  }
+
+  static std::unique_ptr<Comparator> LongComparator(const std::string& value) 
noexcept {
+    // TODO: this should take a uint64_t argument, not a byte array.
+    auto data = std::make_unique<pb::LongComparator>();
+    data->set_allocated_comparable(ByteArrayComparable(value).release());
+    return 
std::make_unique<Comparator>("org.apache.hadoop.hbase.filter.LongComparator",
+                                        std::move(data));
+  }
+
+  static std::unique_ptr<Comparator> BinaryPrefixComparator(const std::string& 
value) noexcept {
+    auto data = std::make_unique<pb::BinaryPrefixComparator>();
+    data->set_allocated_comparable(ByteArrayComparable(value).release());
+    return 
std::make_unique<Comparator>("org.apache.hadoop.hbase.filter.BinaryPrefixComparator",
+                                        std::move(data));
+  }
+
+  static std::unique_ptr<Comparator> BitComparator(const std::string& value,
+                                                   pb::BitComparator_BitwiseOp 
bit_op) noexcept {
+    auto data = std::make_unique<pb::BitComparator>();
+    data->set_allocated_comparable(ByteArrayComparable(value).release());
+    data->set_bitwise_op(bit_op);
+    return 
std::make_unique<Comparator>("org.apache.hadoop.hbase.filter.BitComparator",
+                                        std::move(data));
+  }
+
+  static std::unique_ptr<Comparator> NullComparator() noexcept {
+    auto data = std::make_unique<pb::NullComparator>();
+    return 
std::make_unique<Comparator>("org.apache.hadoop.hbase.filter.NullComparator",
+                                        std::move(data));
+  }
+
+  /**
+   * @param pattern a valid regular expression
+   * @param pattern_flags java.util.regex.Pattern flags
+   * @param charset the charset name
+   * @param engine engine implementation type, either JAVA or JONI
+   */
+  static std::unique_ptr<Comparator> RegexStringComparator(
+      const std::string& pattern, int32_t pattern_flags, const std::string& 
charset = "UTF-8",
+      const std::string& engine = "JAVA") noexcept {
+    auto data = std::make_unique<pb::RegexStringComparator>();
+    data->set_pattern(pattern);
+    data->set_pattern_flags(pattern_flags);
+    data->set_charset(charset);
+    data->set_engine(engine);
+    return 
std::make_unique<Comparator>("org.apache.hadoop.hbase.filter.RegexStringComparator",
+                                        std::move(data));
+  }
+
+  static std::unique_ptr<Comparator> SubstringComparator(const std::string& 
substr) noexcept {
+    auto data = std::make_unique<pb::SubstringComparator>();
+    data->set_substr(substr);
+    return 
std::make_unique<Comparator>("org.apache.hadoop.hbase.filter.SubstringComparator",
+                                        std::move(data));
+  }
+};
+}  // namespace hbase

http://git-wip-us.apache.org/repos/asf/hbase/blob/c561d572/hbase-native-client/core/get.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/get.h b/hbase-native-client/core/get.h
index f79c633..92d1fee 100644
--- a/hbase-native-client/core/get.h
+++ b/hbase-native-client/core/get.h
@@ -24,6 +24,7 @@
 #include <memory>
 #include <string>
 #include <vector>
+#include "core/query.h"
 #include "core/time_range.h"
 #include "if/Client.pb.h"
 
@@ -35,7 +36,7 @@ namespace hbase {
  */
 using FamilyMap = std::map<std::string, std::vector<std::string>>;
 
-class Get {
+class Get : public Query {
  public:
   /**
    * Constructors

http://git-wip-us.apache.org/repos/asf/hbase/blob/c561d572/hbase-native-client/core/query.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/query.h b/hbase-native-client/core/query.h
new file mode 100644
index 0000000..b706303
--- /dev/null
+++ b/hbase-native-client/core/query.h
@@ -0,0 +1,41 @@
+/*
+ * 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 "core/filter.h"
+
+namespace hbase {
+
+/**
+ * Base class for read RPC calls (Get / Scan).
+ */
+class Query {
+ public:
+  virtual ~Query() {}
+
+  void SetFilter(std::unique_ptr<Filter> filter) { filter_ = 
std::move(filter); }
+
+  const std::unique_ptr<Filter>& filter() const { return filter_; }
+
+ protected:
+  std::unique_ptr<Filter> filter_ = nullptr;
+};
+
+}  // namespace hbase

http://git-wip-us.apache.org/repos/asf/hbase/blob/c561d572/hbase-native-client/core/request_converter.cc
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/request_converter.cc 
b/hbase-native-client/core/request_converter.cc
index eba07df..149202e 100644
--- a/hbase-native-client/core/request_converter.cc
+++ b/hbase-native-client/core/request_converter.cc
@@ -68,6 +68,10 @@ std::unique_ptr<Request> 
RequestConverter::ToGetRequest(const Get &get,
     }
   }
 
+  if (get.filter() != nullptr) {
+    pb_get->set_allocated_filter(Filter::ToProto(*(get.filter())).release());
+  }
+
   return pb_req;
 }
 
@@ -108,6 +112,10 @@ std::unique_ptr<Request> 
RequestConverter::ToScanRequest(const Scan &scan,
     }
   }
 
+  if (scan.filter() != nullptr) {
+    pb_scan->set_allocated_filter(Filter::ToProto(*(scan.filter())).release());
+  }
+
   // TODO We will change this later.
   pb_msg->set_client_handles_partials(false);
   pb_msg->set_client_handles_heartbeats(false);

http://git-wip-us.apache.org/repos/asf/hbase/blob/c561d572/hbase-native-client/core/scan.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/scan.h b/hbase-native-client/core/scan.h
index e2e7f1a..7e8c7bd 100644
--- a/hbase-native-client/core/scan.h
+++ b/hbase-native-client/core/scan.h
@@ -36,7 +36,7 @@ namespace hbase {
  */
 using FamilyMap = std::map<std::string, std::vector<std::string>>;
 
-class Scan {
+class Scan : public Query {
  public:
   /**
    * @brief Constructors. Create a Scan operation across all rows.

Reply via email to