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����������������������������...ダウンロード