[Groonga-commit] groonga/grnxx at 68c4626 [master] Separate implementations from grnxx::Column.

アーカイブの一覧に戻る

susumu.yata null+****@clear*****
Mon Oct 6 23:39:14 JST 2014


susumu.yata	2014-10-06 23:39:14 +0900 (Mon, 06 Oct 2014)

  New Revision: 68c462689715980916b171790da6073df610d3ec
  https://github.com/groonga/grnxx/commit/68c462689715980916b171790da6073df610d3ec

  Message:
    Separate implementations from grnxx::Column.

  Added files:
    lib/grnxx/impl/column.hpp
    lib/grnxx/impl/column/Makefile.am
    lib/grnxx/impl/column/column_base.cpp
  Copied files:
    lib/grnxx/impl/column/column_base.hpp
      (from include/grnxx/column.hpp)
  Modified files:
    configure.ac
    include/grnxx/column.hpp
    include/grnxx/index.hpp
    lib/grnxx/column.cpp
    lib/grnxx/column_impl.hpp
    lib/grnxx/impl/Makefile.am
    lib/grnxx/impl/table.cpp
    lib/grnxx/impl/table.hpp

  Modified: configure.ac (+1 -0)
===================================================================
--- configure.ac    2014-10-06 22:24:31 +0900 (d354b9c)
+++ configure.ac    2014-10-06 23:39:14 +0900 (8fe75d3)
@@ -57,6 +57,7 @@ AC_CONFIG_FILES([Makefile
                  lib/Makefile
                  lib/grnxx/Makefile
                  lib/grnxx/impl/Makefile
+                 lib/grnxx/impl/column/Makefile
                  src/Makefile
                  test/Makefile
                  benchmark/Makefile])

  Modified: include/grnxx/column.hpp (+24 -131)
===================================================================
--- include/grnxx/column.hpp    2014-10-06 22:24:31 +0900 (457d8d1)
+++ include/grnxx/column.hpp    2014-10-06 23:39:14 +0900 (38a8a6c)
@@ -1,45 +1,27 @@
 #ifndef GRNXX_COLUMN_HPP
 #define GRNXX_COLUMN_HPP
 
-#include "grnxx/name.hpp"
 #include "grnxx/types.hpp"
 
 namespace grnxx {
-namespace impl {
-
-class Table;
-
-}  // namespace impl
 
 class Column {
  public:
-  virtual ~Column();
+  Column() = default;
 
   // Return the table.
-  Table *table() const {
-    return reinterpret_cast<Table *>(table_);
-  }
+  virtual Table *table() const = 0;
   // Return the name.
-  StringCRef name() const {
-    return name_.ref();
-  }
+  virtual StringCRef name() const = 0;
   // Return the data type.
-  DataType data_type() const {
-    return data_type_;
-  }
+  virtual DataType data_type() const = 0;
   // Return the referenced (parent) table, or nullptr if the column is not a
   // reference column.
-  Table *ref_table() const {
-    return reinterpret_cast<Table *>(ref_table_);
-  }
+  virtual Table *ref_table() const = 0;
   // Return whether the column has the key attribute or not.
-  bool has_key_attribute() const {
-    return has_key_attribute_;
-  }
+  virtual bool has_key_attribute() const = 0;
   // Return the number of indexes.
-  Int num_indexes() const {
-    return indexes_.size();
-  }
+  virtual Int num_indexes() const = 0;
 
   // Create an index with "name", "index_type", and "index_options".
   //
@@ -50,7 +32,7 @@ class Column {
       Error *error,
       const StringCRef &name,
       IndexType type,
-      const IndexOptions &options = IndexOptions());
+      const IndexOptions &options = IndexOptions()) = 0;
 
   // Remove an index named "name".
   //
@@ -59,16 +41,16 @@ class Column {
   // "error" != nullptr.
   //
   // Note: Pointers to the removed index must not be used after deletion.
-  bool remove_index(Error *error, const StringCRef &name);
+  virtual bool remove_index(Error *error, const StringCRef &name) = 0;
 
   // Rename an index named "name" to "new_name".
   //
   // On success, returns true.
   // On failure, returns false and stores error information into "*error" if
   // "error" != nullptr.
-  bool rename_index(Error *error,
-                    const StringCRef &name,
-                    const StringCRef &new_name);
+  virtual bool rename_index(Error *error,
+                            const StringCRef &name,
+                            const StringCRef &new_name) = 0;
 
   // Change the order of indexes.
   //
@@ -81,9 +63,9 @@ class Column {
   // On success, returns true.
   // On failure, returns false and stores error information into "*error" if
   // "error" != nullptr.
-  bool reorder_index(Error *error,
-                     const StringCRef &name,
-                     const StringCRef &prev_name);
+  virtual bool reorder_index(Error *error,
+                             const StringCRef &name,
+                             const StringCRef &prev_name) = 0;
 
   // Get an index identified by "index_id".
   //
@@ -92,23 +74,21 @@ class Column {
   // On success, returns a pointer to the index.
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
-  Index *get_index(Int index_id) const {
-    return indexes_[index_id].get();
-  }
+  virtual Index *get_index(Int index_id) const = 0;
 
   // Find an index named "name".
   //
   // On success, returns a pointer to the index.
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
-  Index *find_index(Error *error, const StringCRef &name) const;
+  virtual Index *find_index(Error *error, const StringCRef &name) const = 0;
 
   // Set a value.
   //
   // On success, returns true.
   // On failure, returns false and stores error information into "*error" if
   // "error" != nullptr.
-  virtual bool set(Error *error, Int row_id, const Datum &datum);
+  virtual bool set(Error *error, Int row_id, const Datum &datum) = 0;
 
   // Get a value.
   //
@@ -117,109 +97,22 @@ class Column {
   // On success, returns true.
   // On failure, returns false and stores error information into "*error" if
   // "error" != nullptr.
-  virtual bool get(Error *error, Int row_id, Datum *datum) const;
+  virtual bool get(Error *error, Int row_id, Datum *datum) const = 0;
 
   // Check if "datum" exists in the column or not.
   //
   // If exists, returns true.
   // Otherwise, returns false.
-  virtual bool contains(const Datum &datum) const;
+  virtual bool contains(const Datum &datum) const = 0;
 
   // Find "datum" in the column.
   //
-  // If found, returns the row ID of the matched value.
-  // Otherwise, returns NULL_ROW_ID.
-  virtual Int find_one(const Datum &datum) const;
-
-  // TODO: This function should be hidden.
-  //
-  // Return the referenced (parent) table, or nullptr if the column is not a
-  // reference column.
-  impl::Table *_ref_table() const {
-    return ref_table_;
-  }
-
-  // TODO: This function should be hidden.
-  //
-  // Replace references to "row_id" with NULL.
-  virtual void clear_references(Int row_id);
+  // On success, returns the row ID of the matched value.
+  // On failure, returns NULL_ROW_ID.
+  virtual Int find_one(const Datum &datum) const = 0;
 
  protected:
-  impl::Table *table_;
-  Name name_;
-  DataType data_type_;
-  impl::Table *ref_table_;
-  bool has_key_attribute_;
-  Array<unique_ptr<Index>> indexes_;
-
-  Column();
-
-  // Initialize the base members.
-  //
-  // On success, returns true.
-  // On failure, returns false and stores error information into "*error" if
-  // "error" != nullptr.
-  bool initialize_base(Error *error,
-                       Table *table,
-                       const StringCRef &name,
-                       DataType data_type,
-                       const ColumnOptions &options = ColumnOptions());
-
- private:
-  // Create a new column.
-  //
-  // On success, returns a pointer to the column.
-  // On failure, returns nullptr and stores error information into "*error" if
-  // "error" != nullptr.
-  static unique_ptr<Column> create(
-      Error *error,
-      Table *table,
-      const StringCRef &name,
-      DataType data_type,
-      const ColumnOptions &options = ColumnOptions());
-
-  // Change the column name.
-  //
-  // On success, returns true.
-  // On failure, returns false and stores error information into "*error" if
-  // "error" != nullptr.
-  bool rename(Error *error, const StringCRef &new_name);
-
-  // Return whether the column is removable or not.
-  bool is_removable();
-
-  // Set the key attribute.
-  virtual bool set_key_attribute(Error *error);
-  // Unset the key attribute.
-  virtual bool unset_key_attribute(Error *error);
-
-  // Set the initial key.
-  //
-  // On success, returns true.
-  // On failure, returns false and stores error information into "*error" if
-  // "error" != nullptr.
-  virtual bool set_initial_key(Error *error, Int row_id, const Datum &key);
-
-  // Set the default value.
-  //
-  // On success, returns true.
-  // On failure, returns false and stores error information into "*error" if
-  // "error" != nullptr.
-  virtual bool set_default_value(Error *error, Int row_id) = 0;
-
-  // Unset the value.
-  virtual void unset(Int row_id) = 0;
-
-  // Find an index with its ID.
-  //
-  // On success, returns a pointer to the index.
-  // On failure, returns nullptr and stores error information into "*error" if
-  // "error" != nullptr.
-  Index *find_index_with_id(Error *error,
-                            const StringCRef &name,
-                            Int *column_id) const;
-
-  friend class impl::Table;
+  virtual ~Column() = default;
 };
 
 }  // namespace grnxx

  Modified: include/grnxx/index.hpp (+6 -1)
===================================================================
--- include/grnxx/index.hpp    2014-10-06 22:24:31 +0900 (e79d76e)
+++ include/grnxx/index.hpp    2014-10-06 23:39:14 +0900 (ab70f7b)
@@ -5,6 +5,11 @@
 #include "grnxx/types.hpp"
 
 namespace grnxx {
+namespace impl {
+
+class ColumnBase;
+
+}  // namespace impl
 
 enum EndPointType {
   INCLUSIVE_END_POINT,
@@ -188,7 +193,7 @@ class Index {
   // Return whether the index is removable or not.
   bool is_removable();
 
-  friend class Column;
+  friend class impl::ColumnBase;
 };
 
 }  // namespace grnxx

  Modified: lib/grnxx/column.cpp (+25 -246)
===================================================================
--- lib/grnxx/column.cpp    2014-10-06 22:24:31 +0900 (4abcc11)
+++ lib/grnxx/column.cpp    2014-10-06 23:39:14 +0900 (fc9a04e)
@@ -11,238 +11,6 @@
 
 namespace grnxx {
 
-Column::~Column() {}
-
-Index *Column::create_index(Error *error,
-                            const StringCRef &name,
-                            IndexType type,
-                            const IndexOptions &options) {
-  if (find_index(nullptr, name)) {
-    GRNXX_ERROR_SET(error, ALREADY_EXISTS,
-                    "Index already exists: name = \"%.*s\"",
-                    static_cast<int>(name.size()), name.data());
-    return nullptr;
-  }
-  if (!indexes_.reserve(error, indexes_.size() + 1)) {
-    return nullptr;
-  }
-  unique_ptr<Index> new_index =
-      Index::create(error, this, name, type, options);
-  if (!new_index) {
-    return nullptr;
-  }
-  indexes_.push_back(error, std::move(new_index));
-  return indexes_.back().get();
-}
-
-bool Column::remove_index(Error *error, const StringCRef &name) {
-  Int index_id;
-  if (!find_index_with_id(error, name, &index_id)) {
-    return false;
-  }
-  if (!indexes_[index_id]->is_removable()) {
-    GRNXX_ERROR_SET(error, NOT_REMOVABLE,
-                    "Index is not removable: name = \"%.*s\"",
-                    static_cast<int>(name.size()), name.data());
-    return false;
-  }
-  indexes_.erase(index_id);
-  return true;
-}
-
-bool Column::rename_index(Error *error,
-                          const StringCRef &name,
-                          const StringCRef &new_name) {
-  Int index_id;
-  if (!find_index_with_id(error, name, &index_id)) {
-    return false;
-  }
-  if (name == new_name) {
-    return true;
-  }
-  if (find_index(nullptr, new_name)) {
-    GRNXX_ERROR_SET(error, ALREADY_EXISTS,
-                    "Index already exists: new_name = \"%.*s\"",
-                    static_cast<int>(new_name.size()), new_name.data());
-    return false;
-  }
-  return indexes_[index_id]->rename(error, new_name);
-}
-
-bool Column::reorder_index(Error *error,
-                           const StringCRef &name,
-                           const StringCRef &prev_name) {
-  Int index_id;
-  if (!find_index_with_id(error, name, &index_id)) {
-    return false;
-  }
-  Int new_index_id = 0;
-  if (prev_name.size() != 0) {
-    Int prev_index_id;
-    if (!find_index_with_id(error, prev_name, &prev_index_id)) {
-      return false;
-    }
-    if (index_id <= prev_index_id) {
-      new_index_id = prev_index_id;
-    } else {
-      new_index_id = prev_index_id + 1;
-    }
-  }
-  for ( ; index_id < new_index_id; ++index_id) {
-    std::swap(indexes_[index_id], indexes_[index_id + 1]);
-  }
-  for ( ; index_id > new_index_id; --index_id) {
-    std::swap(indexes_[index_id], indexes_[index_id - 1]);
-  }
-  return true;
-}
-
-Index *Column::find_index(Error *error, const StringCRef &name) const {
-  for (Int index_id = 0; index_id < num_indexes(); ++index_id) {
-    if (name == indexes_[index_id]->name()) {
-      return indexes_[index_id].get();
-    }
-  }
-  GRNXX_ERROR_SET(error, NOT_FOUND, "Index not found");
-  return nullptr;
-}
-
-bool Column::set(Error *error, Int, const Datum &) {
-  GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
-  return false;
-}
-
-bool Column::get(Error *error, Int, Datum *) const {
-  GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
-  return false;
-}
-
-bool Column::contains(const Datum &datum) const {
-  return find_one(datum) != NULL_ROW_ID;
-}
-
-Int Column::find_one(const Datum &) const {
-  // TODO: This function should be pure virtual.
-  return NULL_ROW_ID;
-}
-
-void Column::clear_references(Int) {
-}
-
-unique_ptr<Column> Column::create(Error *error,
-                                  Table *table,
-                                  const StringCRef &name,
-                                  DataType data_type,
-                                  const ColumnOptions &options) {
-  switch (data_type) {
-    case BOOL_DATA: {
-      return ColumnImpl<Bool>::create(error, table, name, options);
-    }
-    case INT_DATA: {
-      return ColumnImpl<Int>::create(error, table, name, options);
-    }
-    case FLOAT_DATA: {
-      return ColumnImpl<Float>::create(error, table, name, options);
-    }
-    case GEO_POINT_DATA: {
-      return ColumnImpl<GeoPoint>::create(error, table, name, options);
-    }
-    case TEXT_DATA: {
-      return ColumnImpl<Text>::create(error, table, name, options);
-    }
-    case BOOL_VECTOR_DATA: {
-      return ColumnImpl<Vector<Bool>>::create(error, table, name, options);
-    }
-    case INT_VECTOR_DATA: {
-      return ColumnImpl<Vector<Int>>::create(error, table, name, options);
-    }
-    case FLOAT_VECTOR_DATA: {
-      return ColumnImpl<Vector<Float>>::create(error, table, name, options);
-    }
-    case GEO_POINT_VECTOR_DATA: {
-      return ColumnImpl<Vector<GeoPoint>>::create(error, table, name, options);
-    }
-    case TEXT_VECTOR_DATA: {
-      return ColumnImpl<Vector<Text>>::create(error, table, name, options);
-    }
-    default: {
-      // TODO: Other data types are not supported yet.
-      GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
-      return nullptr;
-    }
-  }
-}
-
-Column::Column()
-    : table_(nullptr),
-      name_(),
-      data_type_(),
-      ref_table_(nullptr),
-      has_key_attribute_(false) {}
-
-bool Column::initialize_base(Error *error,
-                             Table *table,
-                             const StringCRef &name,
-                             DataType data_type,
-                             const ColumnOptions &options) {
-  table_ = static_cast<impl::Table *>(table);
-  if (!name_.assign(error, name)) {
-    return false;
-  }
-  data_type_ = data_type;
-  if ((data_type == INT_DATA) || (data_type == INT_VECTOR_DATA)) {
-    if (options.ref_table_name.size() != 0) {
-      auto ref_table = table_->_db()->find_table(error, options.ref_table_name);
-      if (!ref_table) {
-        return false;
-      }
-      ref_table_ = static_cast<impl::Table *>(ref_table);
-    }
-  }
-  return true;
-}
-
-bool Column::rename(Error *error, const StringCRef &new_name) {
-  return name_.assign(error, new_name);
-}
-
-bool Column::is_removable() {
-  // TODO: Reference column is not supported yet.
-  return true;
-}
-
-bool Column::set_initial_key(Error *error, Int, const Datum &) {
-  // TODO: Key column is not supported yet.
-  GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
-  return false;
-}
-
-bool Column::set_key_attribute(Error *error) {
-  GRNXX_ERROR_SET(error, INVALID_OPERATION, "This type does not support Key");
-  return false;
-}
-
-bool Column::unset_key_attribute(Error *error) {
-  GRNXX_ERROR_SET(error, INVALID_OPERATION, "This type does not support Key");
-  return false;
-}
-
-Index *Column::find_index_with_id(Error *error,
-                                  const StringCRef &name,
-                                  Int *index_id) const {
-  for (Int i = 0; i < num_indexes(); ++i) {
-    if (name == indexes_[i]->name()) {
-      if (index_id != nullptr) {
-        *index_id = i;
-      }
-      return indexes_[i].get();
-    }
-  }
-  GRNXX_ERROR_SET(error, NOT_FOUND, "Index not found: name = \"%.*s\"",
-                  static_cast<int>(name.size()), name.data());
-  return nullptr;
-}
-
 // -- ColumnImpl<T> --
 
 template <typename T>
@@ -287,7 +55,7 @@ bool ColumnImpl<T>::get(Error *error, Int row_id, Datum *datum) const {
 
 template <typename T>
 unique_ptr<ColumnImpl<T>> ColumnImpl<T>::create(Error *error,
-                                                Table *table,
+                                                impl::Table *table,
                                                 const StringCRef &name,
                                                 const ColumnOptions &options) {
   unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl);
@@ -338,7 +106,12 @@ void ColumnImpl<T>::unset(Int row_id) {
 }
 
 template <typename T>
-ColumnImpl<T>::ColumnImpl() : Column(), values_() {}
+ColumnImpl<T>::ColumnImpl() : ColumnBase(), values_() {}
+
+template class ColumnImpl<Bool>;
+template class ColumnImpl<Float>;
+template class ColumnImpl<GeoPoint>;
+template class ColumnImpl<Vector<Bool>>;
 
 // -- ColumnImpl<Int> --
 
@@ -388,7 +161,7 @@ bool ColumnImpl<Int>::get(Error *error, Int row_id, Datum *datum) const {
 
 unique_ptr<ColumnImpl<Int>> ColumnImpl<Int>::create(
     Error *error,
-    Table *table,
+    impl::Table *table,
     const StringCRef &name,
     const ColumnOptions &options) {
   unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl);
@@ -605,7 +378,7 @@ void ColumnImpl<Int>::clear_references(Int row_id) {
   }
 }
 
-ColumnImpl<Int>::ColumnImpl() : Column(), values_() {}
+ColumnImpl<Int>::ColumnImpl() : ColumnBase(), values_() {}
 
 // -- ColumnImpl<Text> --
 
@@ -671,7 +444,7 @@ bool ColumnImpl<Text>::get(Error *error, Int row_id, Datum *datum) const {
 
 unique_ptr<ColumnImpl<Text>> ColumnImpl<Text>::create(
     Error *error,
-    Table *table,
+    impl::Table *table,
     const StringCRef &name,
     const ColumnOptions &options) {
   unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl);
@@ -861,7 +634,7 @@ Int ColumnImpl<Text>::find_one(const Datum &datum) const {
   return NULL_ROW_ID;
 }
 
-ColumnImpl<Text>::ColumnImpl() : Column(), headers_(), bodies_() {}
+ColumnImpl<Text>::ColumnImpl() : ColumnBase(), headers_(), bodies_() {}
 
 // -- ColumnImpl<Vector<Int>> --
 
@@ -920,7 +693,7 @@ bool ColumnImpl<Vector<Int>>::get(Error *error, Int row_id,
 
 unique_ptr<ColumnImpl<Vector<Int>>> ColumnImpl<Vector<Int>>::create(
     Error *error,
-    Table *table,
+    impl::Table *table,
     const StringCRef &name,
     const ColumnOptions &options) {
   unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl);
@@ -1005,7 +778,7 @@ void ColumnImpl<Vector<Int>>::clear_references(Int row_id) {
   }
 }
 
-ColumnImpl<Vector<Int>>::ColumnImpl() : Column(), headers_(), bodies_() {}
+ColumnImpl<Vector<Int>>::ColumnImpl() : ColumnBase(), headers_(), bodies_() {}
 
 // -- ColumnImpl<Vector<Float>> --
 
@@ -1058,7 +831,7 @@ bool ColumnImpl<Vector<Float>>::get(Error *error, Int row_id,
 
 unique_ptr<ColumnImpl<Vector<Float>>> ColumnImpl<Vector<Float>>::create(
     Error *error,
-    Table *table,
+    impl::Table *table,
     const StringCRef &name,
     const ColumnOptions &options) {
   unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl);
@@ -1092,7 +865,10 @@ void ColumnImpl<Vector<Float>>::unset(Int row_id) {
   headers_[row_id] = 0;
 }
 
-ColumnImpl<Vector<Float>>::ColumnImpl() : Column(), headers_(), bodies_() {}
+ColumnImpl<Vector<Float>>::ColumnImpl()
+    : ColumnBase(),
+      headers_(),
+      bodies_() {}
 
 // -- ColumnImpl<Vector<GeoPoint>> --
 
@@ -1145,7 +921,7 @@ bool ColumnImpl<Vector<GeoPoint>>::get(Error *error, Int row_id,
 
 unique_ptr<ColumnImpl<Vector<GeoPoint>>> ColumnImpl<Vector<GeoPoint>>::create(
     Error *error,
-    Table *table,
+    impl::Table *table,
     const StringCRef &name,
     const ColumnOptions &options) {
   unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl);
@@ -1180,7 +956,10 @@ void ColumnImpl<Vector<GeoPoint>>::unset(Int row_id) {
   headers_[row_id] = 0;
 }
 
-ColumnImpl<Vector<GeoPoint>>::ColumnImpl() : Column(), headers_(), bodies_() {}
+ColumnImpl<Vector<GeoPoint>>::ColumnImpl()
+    : ColumnBase(),
+      headers_(),
+      bodies_() {}
 
 // -- ColumnImpl<Vector<Text>> --
 
@@ -1231,7 +1010,7 @@ bool ColumnImpl<Vector<Text>>::get(Error *error, Int row_id,
 
 unique_ptr<ColumnImpl<Vector<Text>>> ColumnImpl<Vector<Text>>::create(
     Error *error,
-    Table *table,
+    impl::Table *table,
     const StringCRef &name,
     const ColumnOptions &options) {
   unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl);
@@ -1268,7 +1047,7 @@ void ColumnImpl<Vector<Text>>::unset(Int row_id) {
 }
 
 ColumnImpl<Vector<Text>>::ColumnImpl()
-    : Column(),
+    : ColumnBase(),
       headers_(),
       text_headers_(),
       bodies_() {}

  Modified: lib/grnxx/column_impl.hpp (+15 -15)
===================================================================
--- lib/grnxx/column_impl.hpp    2014-10-06 22:24:31 +0900 (11567e7)
+++ lib/grnxx/column_impl.hpp    2014-10-06 23:39:14 +0900 (68b5a6c)
@@ -1,12 +1,12 @@
 #ifndef GRNXX_COLUMN_IMPL_HPP
 #define GRNXX_COLUMN_IMPL_HPP
 
-#include "grnxx/column.hpp"
+#include "grnxx/impl/column/column_base.hpp"
 
 namespace grnxx {
 
 template <typename T>
-class ColumnImpl : public Column {
+class ColumnImpl : public impl::ColumnBase {
  public:
   // -- Public API --
 
@@ -21,7 +21,7 @@ class ColumnImpl : public Column {
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
   static unique_ptr<ColumnImpl> create(Error *error,
-                                       Table *table,
+                                       impl::Table *table,
                                        const StringCRef &name,
                                        const ColumnOptions &options);
 
@@ -51,7 +51,7 @@ class ColumnImpl : public Column {
 };
 
 template <>
-class ColumnImpl<Int> : public Column {
+class ColumnImpl<Int> : public impl::ColumnBase {
  public:
   // -- Public API --
 
@@ -66,7 +66,7 @@ class ColumnImpl<Int> : public Column {
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
   static unique_ptr<ColumnImpl> create(Error *error,
-                                       Table *table,
+                                       impl::Table *table,
                                        const StringCRef &name,
                                        const ColumnOptions &options);
 
@@ -103,7 +103,7 @@ class ColumnImpl<Int> : public Column {
 };
 
 template <>
-class ColumnImpl<Text> : public Column {
+class ColumnImpl<Text> : public impl::ColumnBase {
  public:
   // -- Public API --
 
@@ -118,7 +118,7 @@ class ColumnImpl<Text> : public Column {
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
   static unique_ptr<ColumnImpl> create(Error *error,
-                                       Table *table,
+                                       impl::Table *table,
                                        const StringCRef &name,
                                        const ColumnOptions &options);
 
@@ -165,7 +165,7 @@ class ColumnImpl<Text> : public Column {
 };
 
 template <>
-class ColumnImpl<Vector<Int>> : public Column {
+class ColumnImpl<Vector<Int>> : public impl::ColumnBase {
  public:
   // -- Public API --
 
@@ -180,7 +180,7 @@ class ColumnImpl<Vector<Int>> : public Column {
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
   static unique_ptr<ColumnImpl> create(Error *error,
-                                       Table *table,
+                                       impl::Table *table,
                                        const StringCRef &name,
                                        const ColumnOptions &options);
 
@@ -224,7 +224,7 @@ class ColumnImpl<Vector<Int>> : public Column {
 };
 
 template <>
-class ColumnImpl<Vector<Float>> : public Column {
+class ColumnImpl<Vector<Float>> : public impl::ColumnBase {
  public:
   // -- Public API --
 
@@ -239,7 +239,7 @@ class ColumnImpl<Vector<Float>> : public Column {
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
   static unique_ptr<ColumnImpl> create(Error *error,
-                                       Table *table,
+                                       impl::Table *table,
                                        const StringCRef &name,
                                        const ColumnOptions &options);
 
@@ -281,7 +281,7 @@ class ColumnImpl<Vector<Float>> : public Column {
 };
 
 template <>
-class ColumnImpl<Vector<GeoPoint>> : public Column {
+class ColumnImpl<Vector<GeoPoint>> : public impl::ColumnBase {
  public:
   // -- Public API --
 
@@ -296,7 +296,7 @@ class ColumnImpl<Vector<GeoPoint>> : public Column {
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
   static unique_ptr<ColumnImpl> create(Error *error,
-                                       Table *table,
+                                       impl::Table *table,
                                        const StringCRef &name,
                                        const ColumnOptions &options);
 
@@ -340,7 +340,7 @@ class ColumnImpl<Vector<GeoPoint>> : public Column {
 
 // TODO: Improve the implementation.
 template <>
-class ColumnImpl<Vector<Text>> : public Column {
+class ColumnImpl<Vector<Text>> : public impl::ColumnBase {
  public:
   // -- Public API --
 
@@ -355,7 +355,7 @@ class ColumnImpl<Vector<Text>> : public Column {
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
   static unique_ptr<ColumnImpl> create(Error *error,
-                                       Table *table,
+                                       impl::Table *table,
                                        const StringCRef &name,
                                        const ColumnOptions &options);
 

  Modified: lib/grnxx/impl/Makefile.am (+5 -4)
===================================================================
--- lib/grnxx/impl/Makefile.am    2014-10-06 22:24:31 +0900 (627068c)
+++ lib/grnxx/impl/Makefile.am    2014-10-06 23:39:14 +0900 (cc4ca15)
@@ -1,10 +1,10 @@
-#SUBDIRS =				\
-#	sub
+SUBDIRS =				\
+	column
 
 lib_LTLIBRARIES = libgrnxx_impl.la
 
-#libgrnxx_impl_la_LIBADD =		\
-#	sub/libgrnxx_impl_sub.la
+libgrnxx_impl_la_LIBADD =		\
+	column/libgrnxx_impl_column.la
 
 libgrnxx_impl_la_LDFLAGS = @AM_LTLDFLAGS@
 
@@ -14,5 +14,6 @@ libgrnxx_impl_la_SOURCES =		\
 
 libgrnxx_impl_includedir = ${includedir}/grnxx/impl
 libgrnxx_impl_include_HEADERS =		\
+	column.hpp			\
 	db.hpp				\
 	table.hpp

  Added: lib/grnxx/impl/column.hpp (+16 -0) 100644
===================================================================
--- /dev/null
+++ lib/grnxx/impl/column.hpp    2014-10-06 23:39:14 +0900 (16eb144)
@@ -0,0 +1,16 @@
+#ifndef GRNXX_IMPL_COLUMN_HPP
+#define GRNXX_IMPL_COLUMN_HPP
+
+#include "grnxx/impl/column/column_base.hpp"
+//#include "grnxx/impl/column/column_bool.hpp"
+//#include "grnxx/impl/column/column_int.hpp"
+//#include "grnxx/impl/column/column_float.hpp"
+//#include "grnxx/impl/column/column_geo_point.hpp"
+//#include "grnxx/impl/column/column_text.hpp"
+//#include "grnxx/impl/column/column_vector_bool.hpp"
+//#include "grnxx/impl/column/column_vector_int.hpp"
+//#include "grnxx/impl/column/column_vector_float.hpp"
+//#include "grnxx/impl/column/column_vector_geo_point.hpp"
+//#include "grnxx/impl/column/column_vector_text.hpp"
+
+#endif  // GRNXX_IMPL_COLUMN_HPP

  Added: lib/grnxx/impl/column/Makefile.am (+16 -0) 100644
===================================================================
--- /dev/null
+++ lib/grnxx/impl/column/Makefile.am    2014-10-06 23:39:14 +0900 (8a5ffdc)
@@ -0,0 +1,16 @@
+#SUBDIRS =					\
+#	sub
+
+lib_LTLIBRARIES = libgrnxx_impl_column.la
+
+#libgrnxx_impl_column_la_LIBADD =		\
+#	sub/libgrnxx_impl_column_sub.la
+
+libgrnxx_impl_column_la_LDFLAGS = @AM_LTLDFLAGS@
+
+libgrnxx_impl_column_la_SOURCES =		\
+	column_base.cpp
+
+libgrnxx_impl_column_includedir = ${includedir}/grnxx/impl/column
+libgrnxx_impl_column_include_HEADERS =		\
+	column_base.hpp

  Added: lib/grnxx/impl/column/column_base.cpp (+254 -0) 100644
===================================================================
--- /dev/null
+++ lib/grnxx/impl/column/column_base.cpp    2014-10-06 23:39:14 +0900 (6909edb)
@@ -0,0 +1,254 @@
+#include "grnxx/impl/column/column_base.hpp"
+
+#include "grnxx/column_impl.hpp"
+#include "grnxx/cursor.hpp"
+#include "grnxx/impl/db.hpp"
+#include "grnxx/impl/table.hpp"
+#include "grnxx/index.hpp"
+
+namespace grnxx {
+namespace impl {
+
+ColumnBase::ColumnBase()
+    : grnxx::Column(),
+      table_(nullptr),
+      name_(),
+      data_type_(),
+      ref_table_(nullptr),
+      has_key_attribute_(false) {}
+
+ColumnBase::~ColumnBase() {}
+
+grnxx::Table *ColumnBase::table() const {
+  return table_;
+}
+
+grnxx::Table *ColumnBase::ref_table() const {
+  return ref_table_;
+}
+
+Index *ColumnBase::create_index(Error *error,
+                                const StringCRef &name,
+                                IndexType type,
+                                const IndexOptions &options) {
+  if (find_index(nullptr, name)) {
+    GRNXX_ERROR_SET(error, ALREADY_EXISTS,
+                    "Index already exists: name = \"%.*s\"",
+                    static_cast<int>(name.size()), name.data());
+    return nullptr;
+  }
+  if (!indexes_.reserve(error, indexes_.size() + 1)) {
+    return nullptr;
+  }
+  unique_ptr<Index> new_index =
+      Index::create(error, this, name, type, options);
+  if (!new_index) {
+    return nullptr;
+  }
+  indexes_.push_back(error, std::move(new_index));
+  return indexes_.back().get();
+}
+
+bool ColumnBase::remove_index(Error *error, const StringCRef &name) {
+  Int index_id;
+  if (!find_index_with_id(error, name, &index_id)) {
+    return false;
+  }
+  if (!indexes_[index_id]->is_removable()) {
+    GRNXX_ERROR_SET(error, NOT_REMOVABLE,
+                    "Index is not removable: name = \"%.*s\"",
+                    static_cast<int>(name.size()), name.data());
+    return false;
+  }
+  indexes_.erase(index_id);
+  return true;
+}
+
+bool ColumnBase::rename_index(Error *error,
+                              const StringCRef &name,
+                              const StringCRef &new_name) {
+  Int index_id;
+  if (!find_index_with_id(error, name, &index_id)) {
+    return false;
+  }
+  if (name == new_name) {
+    return true;
+  }
+  if (find_index(nullptr, new_name)) {
+    GRNXX_ERROR_SET(error, ALREADY_EXISTS,
+                    "Index already exists: new_name = \"%.*s\"",
+                    static_cast<int>(new_name.size()), new_name.data());
+    return false;
+  }
+  return indexes_[index_id]->rename(error, new_name);
+}
+
+bool ColumnBase::reorder_index(Error *error,
+                               const StringCRef &name,
+                               const StringCRef &prev_name) {
+  Int index_id;
+  if (!find_index_with_id(error, name, &index_id)) {
+    return false;
+  }
+  Int new_index_id = 0;
+  if (prev_name.size() != 0) {
+    Int prev_index_id;
+    if (!find_index_with_id(error, prev_name, &prev_index_id)) {
+      return false;
+    }
+    if (index_id <= prev_index_id) {
+      new_index_id = prev_index_id;
+    } else {
+      new_index_id = prev_index_id + 1;
+    }
+  }
+  for ( ; index_id < new_index_id; ++index_id) {
+    std::swap(indexes_[index_id], indexes_[index_id + 1]);
+  }
+  for ( ; index_id > new_index_id; --index_id) {
+    std::swap(indexes_[index_id], indexes_[index_id - 1]);
+  }
+  return true;
+}
+
+Index *ColumnBase::find_index(Error *error, const StringCRef &name) const {
+  for (Int index_id = 0; index_id < num_indexes(); ++index_id) {
+    if (name == indexes_[index_id]->name()) {
+      return indexes_[index_id].get();
+    }
+  }
+  GRNXX_ERROR_SET(error, NOT_FOUND, "Index not found");
+  return nullptr;
+}
+
+bool ColumnBase::set(Error *error, Int, const Datum &) {
+  GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
+  return false;
+}
+
+bool ColumnBase::get(Error *error, Int, Datum *) const {
+  GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
+  return false;
+}
+
+bool ColumnBase::contains(const Datum &datum) const {
+  return find_one(datum) != NULL_ROW_ID;
+}
+
+Int ColumnBase::find_one(const Datum &) const {
+  // TODO: This function should be pure virtual.
+  return NULL_ROW_ID;
+}
+
+void ColumnBase::clear_references(Int) {
+}
+
+unique_ptr<ColumnBase> ColumnBase::create(Error *error,
+                                          Table *table,
+                                          const StringCRef &name,
+                                          DataType data_type,
+                                          const ColumnOptions &options) {
+  switch (data_type) {
+    case BOOL_DATA: {
+      return ColumnImpl<Bool>::create(error, table, name, options);
+    }
+    case INT_DATA: {
+      return ColumnImpl<Int>::create(error, table, name, options);
+    }
+    case FLOAT_DATA: {
+      return ColumnImpl<Float>::create(error, table, name, options);
+    }
+    case GEO_POINT_DATA: {
+      return ColumnImpl<GeoPoint>::create(error, table, name, options);
+    }
+    case TEXT_DATA: {
+      return ColumnImpl<Text>::create(error, table, name, options);
+    }
+    case BOOL_VECTOR_DATA: {
+      return ColumnImpl<Vector<Bool>>::create(error, table, name, options);
+    }
+    case INT_VECTOR_DATA: {
+      return ColumnImpl<Vector<Int>>::create(error, table, name, options);
+    }
+    case FLOAT_VECTOR_DATA: {
+      return ColumnImpl<Vector<Float>>::create(error, table, name, options);
+    }
+    case GEO_POINT_VECTOR_DATA: {
+      return ColumnImpl<Vector<GeoPoint>>::create(error, table, name, options);
+    }
+    case TEXT_VECTOR_DATA: {
+      return ColumnImpl<Vector<Text>>::create(error, table, name, options);
+    }
+    default: {
+      // TODO: Other data types are not supported yet.
+      GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
+      return nullptr;
+    }
+  }
+}
+
+bool ColumnBase::initialize_base(Error *error,
+                                 Table *table,
+                                 const StringCRef &name,
+                                 DataType data_type,
+                                 const ColumnOptions &options) {
+  table_ = static_cast<impl::Table *>(table);
+  if (!name_.assign(error, name)) {
+    return false;
+  }
+  data_type_ = data_type;
+  if ((data_type == INT_DATA) || (data_type == INT_VECTOR_DATA)) {
+    if (options.ref_table_name.size() != 0) {
+      auto ref_table = table_->_db()->find_table(error, options.ref_table_name);
+      if (!ref_table) {
+        return false;
+      }
+      ref_table_ = static_cast<impl::Table *>(ref_table);
+    }
+  }
+  return true;
+}
+
+bool ColumnBase::rename(Error *error, const StringCRef &new_name) {
+  return name_.assign(error, new_name);
+}
+
+bool ColumnBase::is_removable() {
+  // TODO: Reference column is not supported yet.
+  return true;
+}
+
+bool ColumnBase::set_initial_key(Error *error, Int, const Datum &) {
+  // TODO: Key column is not supported yet.
+  GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
+  return false;
+}
+
+bool ColumnBase::set_key_attribute(Error *error) {
+  GRNXX_ERROR_SET(error, INVALID_OPERATION, "This type does not support Key");
+  return false;
+}
+
+bool ColumnBase::unset_key_attribute(Error *error) {
+  GRNXX_ERROR_SET(error, INVALID_OPERATION, "This type does not support Key");
+  return false;
+}
+
+Index *ColumnBase::find_index_with_id(Error *error,
+                                      const StringCRef &name,
+                                      Int *index_id) const {
+  for (Int i = 0; i < num_indexes(); ++i) {
+    if (name == indexes_[i]->name()) {
+      if (index_id != nullptr) {
+        *index_id = i;
+      }
+      return indexes_[i].get();
+    }
+  }
+  GRNXX_ERROR_SET(error, NOT_FOUND, "Index not found: name = \"%.*s\"",
+                  static_cast<int>(name.size()), name.data());
+  return nullptr;
+}
+
+}  // namespace impl
+}  // namespace grnxx

  Copied: lib/grnxx/impl/column/column_base.hpp (+57 -111) 64%
===================================================================
--- include/grnxx/column.hpp    2014-10-06 22:24:31 +0900 (457d8d1)
+++ lib/grnxx/impl/column/column_base.hpp    2014-10-06 23:39:14 +0900 (0265c86)
@@ -1,6 +1,7 @@
-#ifndef GRNXX_COLUMN_HPP
-#define GRNXX_COLUMN_HPP
+#ifndef GRNXX_IMPL_COLUMN_COLUMN_BASE_HPP
+#define GRNXX_IMPL_COLUMN_COLUMN_BASE_HPP
 
+#include "grnxx/column.hpp"
 #include "grnxx/name.hpp"
 #include "grnxx/types.hpp"
 
@@ -9,99 +10,69 @@ namespace impl {
 
 class Table;
 
-}  // namespace impl
-
-class Column {
+class ColumnBase : public grnxx::Column {
  public:
-  virtual ~Column();
+  // -- Public API (grnxx/column.hpp) --
 
-  // Return the table.
-  Table *table() const {
-    return reinterpret_cast<Table *>(table_);
-  }
-  // Return the name.
+  ColumnBase();
+  virtual ~ColumnBase();
+
+  grnxx::Table *table() const;
   StringCRef name() const {
     return name_.ref();
   }
-  // Return the data type.
   DataType data_type() const {
     return data_type_;
   }
-  // Return the referenced (parent) table, or nullptr if the column is not a
-  // reference column.
-  Table *ref_table() const {
-    return reinterpret_cast<Table *>(ref_table_);
-  }
-  // Return whether the column has the key attribute or not.
+  grnxx::Table *ref_table() const;
   bool has_key_attribute() const {
     return has_key_attribute_;
   }
-  // Return the number of indexes.
   Int num_indexes() const {
     return indexes_.size();
   }
 
-  // Create an index with "name", "index_type", and "index_options".
-  //
-  // On success, returns a pointer to the index.
-  // On failure, returns nullptr and stores error information into "*error" if
-  // "error" != nullptr.
-  virtual Index *create_index(
+  Index *create_index(
       Error *error,
       const StringCRef &name,
       IndexType type,
       const IndexOptions &options = IndexOptions());
-
-  // Remove an index named "name".
-  //
-  // On success, returns true.
-  // On failure, returns false and stores error information into "*error" if
-  // "error" != nullptr.
-  //
-  // Note: Pointers to the removed index must not be used after deletion.
   bool remove_index(Error *error, const StringCRef &name);
-
-  // Rename an index named "name" to "new_name".
-  //
-  // On success, returns true.
-  // On failure, returns false and stores error information into "*error" if
-  // "error" != nullptr.
   bool rename_index(Error *error,
                     const StringCRef &name,
                     const StringCRef &new_name);
-
-  // Change the order of indexes.
-  //
-  // If "prev_name" is  an empty string, moves an index named "name" to the
-  // head.
-  // If "name" == "prev_name", does nothing.
-  // Otherwise, moves an index named "name" to next to an index named
-  // "prev_name".
-  //
-  // On success, returns true.
-  // On failure, returns false and stores error information into "*error" if
-  // "error" != nullptr.
   bool reorder_index(Error *error,
                      const StringCRef &name,
                      const StringCRef &prev_name);
 
-  // Get an index identified by "index_id".
-  //
-  // If "index_id" is invalid, the result is undefined.
-  //
-  // On success, returns a pointer to the index.
-  // On failure, returns nullptr and stores error information into "*error" if
-  // "error" != nullptr.
   Index *get_index(Int index_id) const {
     return indexes_[index_id].get();
   }
+  Index *find_index(Error *error, const StringCRef &name) const;
+
+  // -- Internal API --
 
-  // Find an index named "name".
+  // Create a new column.
   //
-  // On success, returns a pointer to the index.
+  // On success, returns a pointer to the column.
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
-  Index *find_index(Error *error, const StringCRef &name) const;
+  static unique_ptr<ColumnBase> create(
+      Error *error,
+      Table *table,
+      const StringCRef &name,
+      DataType data_type,
+      const ColumnOptions &options = ColumnOptions());
+
+  // Return the owner table.
+  Table *_table() const {
+    return table_;
+  }
+  // Return the referenced (parent) table, or nullptr if the column is not a
+  // reference column.
+  Table *_ref_table() const {
+    return ref_table_;
+  }
 
   // Set a value.
   //
@@ -131,53 +102,6 @@ class Column {
   // Otherwise, returns NULL_ROW_ID.
   virtual Int find_one(const Datum &datum) const;
 
-  // TODO: This function should be hidden.
-  //
-  // Return the referenced (parent) table, or nullptr if the column is not a
-  // reference column.
-  impl::Table *_ref_table() const {
-    return ref_table_;
-  }
-
-  // TODO: This function should be hidden.
-  //
-  // Replace references to "row_id" with NULL.
-  virtual void clear_references(Int row_id);
-
- protected:
-  impl::Table *table_;
-  Name name_;
-  DataType data_type_;
-  impl::Table *ref_table_;
-  bool has_key_attribute_;
-  Array<unique_ptr<Index>> indexes_;
-
-  Column();
-
-  // Initialize the base members.
-  //
-  // On success, returns true.
-  // On failure, returns false and stores error information into "*error" if
-  // "error" != nullptr.
-  bool initialize_base(Error *error,
-                       Table *table,
-                       const StringCRef &name,
-                       DataType data_type,
-                       const ColumnOptions &options = ColumnOptions());
-
- private:
-  // Create a new column.
-  //
-  // On success, returns a pointer to the column.
-  // On failure, returns nullptr and stores error information into "*error" if
-  // "error" != nullptr.
-  static unique_ptr<Column> create(
-      Error *error,
-      Table *table,
-      const StringCRef &name,
-      DataType data_type,
-      const ColumnOptions &options = ColumnOptions());
-
   // Change the column name.
   //
   // On success, returns true.
@@ -210,6 +134,29 @@ class Column {
   // Unset the value.
   virtual void unset(Int row_id) = 0;
 
+  // Replace references to "row_id" with NULL.
+  virtual void clear_references(Int row_id);
+
+ protected:
+  Table *table_;
+  Name name_;
+  DataType data_type_;
+  Table *ref_table_;
+  bool has_key_attribute_;
+  Array<unique_ptr<Index>> indexes_;
+
+  // Initialize the base members.
+  //
+  // On success, returns true.
+  // On failure, returns false and stores error information into "*error" if
+  // "error" != nullptr.
+  bool initialize_base(Error *error,
+                       Table *table,
+                       const StringCRef &name,
+                       DataType data_type,
+                       const ColumnOptions &options = ColumnOptions());
+
+ private:
   // Find an index with its ID.
   //
   // On success, returns a pointer to the index.
@@ -218,10 +165,9 @@ class Column {
   Index *find_index_with_id(Error *error,
                             const StringCRef &name,
                             Int *column_id) const;
-
-  friend class impl::Table;
 };
 
+}  // namespace impl
 }  // namespace grnxx
 
-#endif  // GRNXX_COLUMN_HPP
+#endif  // GRNXX_IMPL_COLUMN_COLUMN_BASE_HPP

  Modified: lib/grnxx/impl/table.cpp (+14 -15)
===================================================================
--- lib/grnxx/impl/table.cpp    2014-10-06 22:24:31 +0900 (2ec873b)
+++ lib/grnxx/impl/table.cpp    2014-10-06 23:39:14 +0900 (5a801e9)
@@ -1,6 +1,5 @@
 #include "grnxx/impl/table.hpp"
 
-#include "grnxx/column.hpp"
 #include "grnxx/cursor.hpp"
 #include "grnxx/impl/db.hpp"
 
@@ -229,10 +228,10 @@ grnxx::DB *Table::db() const {
   return db_;
 }
 
-Column *Table::create_column(Error *error,
-                             const StringCRef &name,
-                             DataType data_type,
-                             const ColumnOptions &options) {
+ColumnBase *Table::create_column(Error *error,
+                                 const StringCRef &name,
+                                 DataType data_type,
+                                 const ColumnOptions &options) {
   if (find_column(nullptr, name)) {
     GRNXX_ERROR_SET(error, ALREADY_EXISTS,
                     "Column already exists: name = \"%.*s\"",
@@ -242,8 +241,8 @@ Column *Table::create_column(Error *error,
   if (!columns_.reserve(error, columns_.size() + 1)) {
     return nullptr;
   }
-  unique_ptr<Column> new_column =
-      Column::create(error, this, name, data_type, options);
+  unique_ptr<ColumnBase> new_column =
+      ColumnBase::create(error, this, name, data_type, options);
   if (!new_column) {
     return nullptr;
   }
@@ -262,7 +261,7 @@ bool Table::remove_column(Error *error, const StringCRef &name) {
                     static_cast<int>(name.size()), name.data());
     return false;
   }
-  Column *column = columns_[column_id].get();
+  ColumnBase *column = columns_[column_id].get();
   if (column == key_column_) {
     key_column_ = nullptr;
   }
@@ -320,7 +319,7 @@ bool Table::reorder_column(Error *error,
   return true;
 }
 
-Column *Table::find_column(Error *error, const StringCRef &name) const {
+ColumnBase *Table::find_column(Error *error, const StringCRef &name) const {
   for (Int column_id = 0; column_id < num_columns(); ++column_id) {
     if (name == columns_[column_id]->name()) {
       return columns_[column_id].get();
@@ -336,7 +335,7 @@ bool Table::set_key_column(Error *error, const StringCRef &name) {
     GRNXX_ERROR_SET(error, ALREADY_EXISTS, "Key column already exists");
     return false;
   }
-  Column *column = find_column(error, name);
+  ColumnBase *column = find_column(error, name);
   if (!column) {
     return false;
   }
@@ -527,7 +526,7 @@ bool Table::is_removable() {
   return true;
 }
 
-bool Table::append_referrer_column(Error *error, Column *column) {
+bool Table::append_referrer_column(Error *error, ColumnBase *column) {
   if (column->ref_table() != this) {
     GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong column");
     return false;
@@ -535,7 +534,7 @@ bool Table::append_referrer_column(Error *error, Column *column) {
   return referrer_columns_.push_back(error, column);
 }
 
-bool Table::remove_referrer_column(Error *error, Column *column) {
+bool Table::remove_referrer_column(Error *error, ColumnBase *column) {
   for (Int i = 0; i < referrer_columns_.size(); ++i) {
     if (column == referrer_columns_[i]) {
       referrer_columns_.erase(i);
@@ -624,9 +623,9 @@ bool Table::reserve_bit(Error *error, Int i) {
   return true;
 }
 
-Column *Table::find_column_with_id(Error *error,
-                                   const StringCRef &name,
-                                   Int *column_id) const {
+ColumnBase *Table::find_column_with_id(Error *error,
+                                       const StringCRef &name,
+                                       Int *column_id) const {
   for (Int i = 0; i < num_columns(); ++i) {
     if (name == columns_[i]->name()) {
       if (column_id != nullptr) {

  Modified: lib/grnxx/impl/table.hpp (+16 -15)
===================================================================
--- lib/grnxx/impl/table.hpp    2014-10-06 22:24:31 +0900 (2d90117)
+++ lib/grnxx/impl/table.hpp    2014-10-06 23:39:14 +0900 (85752b3)
@@ -3,6 +3,7 @@
 
 #include "grnxx/name.hpp"
 #include "grnxx/db.hpp"
+#include "grnxx/impl/column/column_base.hpp"
 #include "grnxx/table.hpp"
 
 namespace grnxx {
@@ -23,7 +24,7 @@ class Table : public grnxx::Table {
   Int num_columns() const {
     return columns_.size();
   }
-  Column *key_column() const {
+  ColumnBase *key_column() const {
     return key_column_;
   }
   Int num_rows() const {
@@ -33,10 +34,10 @@ class Table : public grnxx::Table {
     return max_row_id_;
   }
 
-  Column *create_column(Error *error,
-                        const StringCRef &name,
-                        DataType data_type,
-                        const ColumnOptions &options = ColumnOptions());
+  ColumnBase *create_column(Error *error,
+                            const StringCRef &name,
+                            DataType data_type,
+                            const ColumnOptions &options = ColumnOptions());
   bool remove_column(Error *error, const StringCRef &name);
   bool rename_column(Error *error,
                      const StringCRef &name,
@@ -45,10 +46,10 @@ class Table : public grnxx::Table {
                       const StringCRef &name,
                       const StringCRef &prev_name);
 
-  Column *get_column(Int column_id) const {
+  ColumnBase *get_column(Int column_id) const {
     return columns_[column_id].get();
   }
-  Column *find_column(Error *error, const StringCRef &name) const;
+  ColumnBase *find_column(Error *error, const StringCRef &name) const;
 
   bool set_key_column(Error *error, const StringCRef &name);
   bool unset_key_column(Error *error);
@@ -99,21 +100,21 @@ class Table : public grnxx::Table {
   // On success, returns true.
   // On failure, returns false and stores error information into "*error" if
   // "error" != nullptr.
-  bool append_referrer_column(Error *error, Column *column);
+  bool append_referrer_column(Error *error, ColumnBase *column);
 
   // Append a referrer column.
   //
   // On success, returns true.
   // On failure, returns false and stores error information into "*error" if
   // "error" != nullptr.
-  bool remove_referrer_column(Error *error, Column *column);
+  bool remove_referrer_column(Error *error, ColumnBase *column);
 
  private:
   DB *db_;
   Name name_;
-  Array<unique_ptr<Column>> columns_;
-  Array<Column *> referrer_columns_;
-  Column *key_column_;
+  Array<unique_ptr<ColumnBase>> columns_;
+  Array<ColumnBase *> referrer_columns_;
+  ColumnBase *key_column_;
   Int num_rows_;
   Int max_row_id_;
   Array<UInt> bitmap_;
@@ -141,9 +142,9 @@ class Table : public grnxx::Table {
   // On success, returns a pointer to the column.
   // On failure, returns nullptr and stores error information into "*error" if
   // "error" != nullptr.
-  Column *find_column_with_id(Error *error,
-                              const StringCRef &name,
-                              Int *column_id) const;
+  ColumnBase *find_column_with_id(Error *error,
+                                  const StringCRef &name,
+                                  Int *column_id) const;
 
   friend class TableCursor;
 };
-------------- next part --------------
HTML����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る