Skip to content

Commit

Permalink
[c++] Column abstraction: SOMAAttribute, part 2 (#3426)
Browse files Browse the repository at this point in the history
* Add concrete class wrapper for TileDB attribute

* Misc fixes

* Add missing `override`

* Remove current_domain flag

* Replace string_view with string when returning column name, add current domain checks, replace vector with span when selecting points

* Update CMake files

* Add description and license

* Address review comments

* Comply with C.128

* Update libtiledbsoma/src/soma/soma_attribute.cc

Co-authored-by: Julia Dark <[email protected]>

* Update libtiledbsoma/src/soma/soma_attribute.h

Co-authored-by: Julia Dark <[email protected]>

---------

Co-authored-by: Julia Dark <[email protected]>
  • Loading branch information
XanthosXanthopoulos and jp-dark authored Jan 3, 2025
1 parent 9e7a461 commit c5ed9da
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 0 deletions.
2 changes: 2 additions & 0 deletions libtiledbsoma/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ add_library(TILEDB_SOMA_OBJECTS OBJECT
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_group.cc
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_object.cc
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_column.cc
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_attribute.cc
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_dimension.cc
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_collection.cc
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_experiment.cc
Expand Down Expand Up @@ -209,6 +210,7 @@ install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_array.h
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_group.h
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_column.h
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_attribute.h
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_dimension.h
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_collection.h
${CMAKE_CURRENT_SOURCE_DIR}/soma/soma_dataframe.h
Expand Down
127 changes: 127 additions & 0 deletions libtiledbsoma/src/soma/soma_attribute.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* @file soma_attribute.cc
*
* @section LICENSE
*
* The MIT License
*
* @copyright Copyright (c) 2024-2025 TileDB, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @section DESCRIPTION
*
* This file defines the SOMAAttribute class.
*/

#include "soma_attribute.h"

namespace tiledbsoma {
std::shared_ptr<SOMAAttribute> SOMAAttribute::create(
std::shared_ptr<Context> ctx,
ArrowSchema* schema,
std::string_view type_metadata,
PlatformConfig platform_config) {
auto attribute = ArrowAdapter::tiledb_attribute_from_arrow_schema(
ctx, schema, type_metadata, platform_config);

return std::make_shared<SOMAAttribute>(
SOMAAttribute(attribute.first, attribute.second));
}

void SOMAAttribute::_set_dim_points(
const std::unique_ptr<ManagedQuery>&,
const SOMAContext&,
const std::any&) const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][_set_dim_points] Column with name {} is not an index "
"column",
name()));
}

void SOMAAttribute::_set_dim_ranges(
const std::unique_ptr<ManagedQuery>&,
const SOMAContext&,
const std::any&) const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][_set_dim_ranges] Column with name {} is not an index "
"column",
name()));
}

void SOMAAttribute::_set_current_domain_slot(
NDRectangle&, std::span<const std::any>) const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][_set_current_domain_slot] Column with name {} is not "
"an index column",
name()));
}

std::pair<bool, std::string> SOMAAttribute::_can_set_current_domain_slot(
std::optional<NDRectangle>&, std::span<const std::any>) const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][_set_current_domain_slot] Column with name {} is not "
"an index column",
name()));
};

std::any SOMAAttribute::_core_domain_slot() const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][_core_domain_slot] Column with name {} is not an "
"index column",
name()));
}

std::any SOMAAttribute::_non_empty_domain_slot(Array&) const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][_non_empty_domain_slot] Column with name {} is not an "
"index column",
name()));
}

std::any SOMAAttribute::_core_current_domain_slot(
const SOMAContext&, Array&) const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][_core_current_domain_slot] Column with name {} is not "
"an index column",
name()));
}

std::any SOMAAttribute::_core_current_domain_slot(NDRectangle&) const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][_core_current_domain_slot] Column with name {} is not "
"an index column",
name()));
}

ArrowArray* SOMAAttribute::arrow_domain_slot(
const SOMAContext&, Array&, enum Domainish) const {
throw TileDBSOMAError(std::format(
"[SOMAAttribute][arrow_domain_slot] Column with name {} is not an "
"index column",
name()));
}

ArrowSchema* SOMAAttribute::arrow_schema_slot(
const SOMAContext& ctx, Array& array) {
return ArrowAdapter::arrow_schema_from_tiledb_attribute(
attribute, *ctx.tiledb_ctx(), array)
.release();
}
} // namespace tiledbsoma
150 changes: 150 additions & 0 deletions libtiledbsoma/src/soma/soma_attribute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/**
* @file soma_attribute.h
*
* @section LICENSE
*
* The MIT License
*
* @copyright Copyright (c) 2024-2025 TileDB, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @section DESCRIPTION
*
* This file defines the SOMAAttribute class. SOMAAttribute extends SOMAColumn
* and wraps a TileDB Attribute and optionally an enumeration associated with
* the attribute. The purpose of this class is to provide a common interface
* identical to TileDB dimensions and composite columns.
*/

#ifndef SOMA_ATTRIBUTE_H
#define SOMA_ATTRIBUTE_H

#include <algorithm>
#include <vector>

#include <tiledb/tiledb>
#include "soma_column.h"

namespace tiledbsoma {
using namespace tiledb;

class SOMAAttribute : public SOMAColumn {
public:
/**
* Create a ``SOMAAttribute`` shared pointer from an Arrow schema
*/
static std::shared_ptr<SOMAAttribute> create(
std::shared_ptr<Context> ctx,
ArrowSchema* schema,
std::string_view type_metadata,
PlatformConfig platform_config);

SOMAAttribute(
Attribute attribute,
std::optional<Enumeration> enumeration = std::nullopt)
: attribute(attribute)
, enumeration(enumeration) {
}

inline std::string name() const override {
return attribute.name();
}

inline bool isIndexColumn() const override {
return false;
}

inline void select_columns(
const std::unique_ptr<ManagedQuery>& query,
bool if_not_empty = false) const override {
query->select_columns(std::vector({attribute.name()}), if_not_empty);
};

inline soma_column_datatype_t type() const override {
return soma_column_datatype_t::SOMA_COLUMN_ATTRIBUTE;
}

inline std::optional<tiledb_datatype_t> domain_type() const override {
return std::nullopt;
}

inline std::optional<tiledb_datatype_t> data_type() const override {
return attribute.type();
}

inline std::optional<std::vector<Dimension>> tiledb_dimensions() override {
return std::nullopt;
}

inline std::optional<std::vector<Attribute>> tiledb_attributes() override {
return std::vector({attribute});
}

inline std::optional<std::vector<Enumeration>> tiledb_enumerations()
override {
if (!enumeration.has_value()) {
return std::nullopt;
}

return std::vector({enumeration.value()});
}

ArrowArray* arrow_domain_slot(
const SOMAContext& ctx,
Array& array,
enum Domainish kind) const override;

ArrowSchema* arrow_schema_slot(
const SOMAContext& ctx, Array& array) override;

private:
void _set_dim_points(
const std::unique_ptr<ManagedQuery>& query,
const SOMAContext& ctx,
const std::any& points) const override;

void _set_dim_ranges(
const std::unique_ptr<ManagedQuery>& query,
const SOMAContext& ctx,
const std::any& ranges) const override;

void _set_current_domain_slot(
NDRectangle& rectangle,
std::span<const std::any> domain) const override;

std::pair<bool, std::string> _can_set_current_domain_slot(
std::optional<NDRectangle>& rectangle,
std::span<const std::any> new_domain) const override;

std::any _core_domain_slot() const override;

std::any _non_empty_domain_slot(Array& array) const override;

std::any _core_current_domain_slot(
const SOMAContext& ctx, Array& array) const override;

std::any _core_current_domain_slot(NDRectangle& ndrect) const override;

Attribute attribute;
std::optional<Enumeration> enumeration;
};
} // namespace tiledbsoma

#endif
1 change: 1 addition & 0 deletions libtiledbsoma/src/tiledbsoma/tiledbsoma
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "soma/soma_array.h"
#include "soma/soma_collection.h"
#include "soma/soma_column.h"
#include "soma/soma_attribute.h"
#include "soma/soma_dimension.h"
#include "soma/soma_dataframe.h"
#include "soma/soma_group.h"
Expand Down
5 changes: 5 additions & 0 deletions libtiledbsoma/test/unit_soma_column.cc
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,11 @@ TEST_CASE_METHOD(
std::make_shared<SOMADimension>(SOMADimension(dimension)));
}

for (size_t i = 0; i < sdf->tiledb_schema()->attribute_num(); ++i) {
columns.push_back(std::make_shared<SOMAAttribute>(
SOMAAttribute(sdf->tiledb_schema()->attribute(i))));
}

CurrentDomain current_domain = sdf->get_current_domain_for_test();

REQUIRE(!current_domain.is_empty());
Expand Down

0 comments on commit c5ed9da

Please sign in to comment.