Skip to content

Commit aad089c

Browse files
rroelkeshaunrd0
andauthored
feat: [sc-58279] [core] add tiledb_array_schema_get_enumeration API (#5359)
Story details: https://app.shortcut.com/tiledb-inc/story/58279 Adds functions `tiledb_array_schema_get_enumeration_from_name` and `tiledb_array_schema_get_enumeration_from_attribute_name` which load the contents of an enumeration and return a handle to the user. --- TYPE: FEATURE | C_API | CPP_API DESC: add tiledb_array_schema_get_enumeration --------- Co-authored-by: Shaun M Reed <[email protected]>
1 parent 83e1419 commit aad089c

24 files changed

+699
-42
lines changed

test/src/unit-cppapi-enumerations.cc

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <fstream>
3434

3535
#include <test/support/tdb_catch.h>
36+
#include "test/support/src/array_schema_helpers.h"
3637
#include "test/support/src/vfs_helpers.h"
3738
#include "tiledb/api/c_api/array/array_api_internal.h"
3839
#include "tiledb/api/c_api/array_schema/array_schema_api_internal.h"
@@ -313,6 +314,96 @@ TEST_CASE_METHOD(
313314
REQUIRE(enmr_name2.has_value() == false);
314315
}
315316

317+
TEST_CASE_METHOD(
318+
CPPEnumerationFx,
319+
"CPP: Enumerations From Disk - ArraySchema::get_enumeration_from_name",
320+
"[enumeration][array-schema-get-enumeration-from-name][rest]") {
321+
create_array();
322+
323+
std::optional<Enumeration> expect_enumeration;
324+
{
325+
auto array = tiledb::Array(ctx_, uri_, TILEDB_READ);
326+
expect_enumeration =
327+
ArrayExperimental::get_enumeration(ctx_, array, enmr_name);
328+
}
329+
330+
SECTION("default schema load retrieves enumeration on request only") {
331+
auto schema = Array::load_schema(ctx_, uri_);
332+
333+
CHECK(!schema.ptr()->array_schema()->is_enumeration_loaded(enmr_name));
334+
335+
auto actual_enumeration =
336+
ArraySchemaExperimental::get_enumeration_from_name(
337+
ctx_, schema, enmr_name);
338+
CHECK(schema.ptr()->array_schema()->is_enumeration_loaded(enmr_name));
339+
CHECK(test::is_equivalent_enumeration(
340+
*expect_enumeration, actual_enumeration));
341+
}
342+
343+
SECTION("schema load with rest config retrieves enumeration eagerly") {
344+
Config config;
345+
config["rest.load_enumerations_on_array_open"] = "true";
346+
347+
auto schema = Array::load_schema_with_config(ctx_, config, uri_);
348+
CHECK(schema.ptr()->array_schema()->is_enumeration_loaded(enmr_name));
349+
350+
// requesting it should do no I/O (we did it already),
351+
// unclear how to check that
352+
auto actual_enumeration =
353+
ArraySchemaExperimental::get_enumeration_from_name(
354+
ctx_, schema, enmr_name);
355+
CHECK(schema.ptr()->array_schema()->is_enumeration_loaded(enmr_name));
356+
CHECK(test::is_equivalent_enumeration(
357+
*expect_enumeration, actual_enumeration));
358+
}
359+
}
360+
361+
TEST_CASE_METHOD(
362+
CPPEnumerationFx,
363+
"CPP: Enumerations From Disk - "
364+
"ArraySchema::get_enumeration_from_attribute_name",
365+
"[enumeration][array-schema-get-enumeration-from-attribute-name][rest]") {
366+
create_array();
367+
368+
const std::string attr_name = "attr1";
369+
370+
std::optional<Enumeration> expect_enumeration;
371+
{
372+
auto array = tiledb::Array(ctx_, uri_, TILEDB_READ);
373+
expect_enumeration =
374+
ArrayExperimental::get_enumeration(ctx_, array, enmr_name);
375+
}
376+
377+
SECTION("default schema load retrieves enumeration on request only") {
378+
auto schema = Array::load_schema(ctx_, uri_);
379+
380+
CHECK(!schema.ptr()->array_schema()->is_enumeration_loaded(enmr_name));
381+
382+
auto actual_enumeration =
383+
ArraySchemaExperimental::get_enumeration_from_attribute_name(
384+
ctx_, schema, attr_name);
385+
CHECK(schema.ptr()->array_schema()->is_enumeration_loaded(enmr_name));
386+
CHECK(test::is_equivalent_enumeration(
387+
*expect_enumeration, actual_enumeration));
388+
}
389+
390+
SECTION("schema load with rest config retrieves enumeration eagerly") {
391+
Config config;
392+
config["rest.load_enumerations_on_array_open"] = "true";
393+
394+
auto schema = Array::load_schema_with_config(ctx_, config, uri_);
395+
CHECK(schema.ptr()->array_schema()->is_enumeration_loaded(enmr_name));
396+
397+
// requesting it should do no I/O (we did it already),
398+
// unclear how to check that
399+
auto actual_enumeration =
400+
ArraySchemaExperimental::get_enumeration_from_attribute_name(
401+
ctx_, schema, attr_name);
402+
CHECK(schema.ptr()->array_schema()->is_enumeration_loaded(enmr_name));
403+
CHECK(test::is_equivalent_enumeration(
404+
*expect_enumeration, actual_enumeration));
405+
}
406+
}
316407
TEST_CASE_METHOD(
317408
CPPEnumerationFx,
318409
"CPP: Array::load_all_enumerations",

test/support/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ list(APPEND TILEDB_CORE_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/tiledb/sm/c_api")
3636

3737
# Gather the test source files
3838
set(TILEDB_TEST_SUPPORT_SOURCES
39+
src/array_schema_helpers.cc
3940
src/ast_helpers.h
4041
src/ast_helpers.cc
4142
src/helpers.h
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @file array_schema_helpers.cc
3+
*
4+
* @section LICENSE
5+
*
6+
* The MIT License
7+
*
8+
* @copyright Copyright (c) 2017-2024 TileDB, Inc.
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* in the Software without restriction, including without limitation the rights
13+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
* copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in
18+
* all copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26+
* THE SOFTWARE.
27+
*
28+
* @section DESCRIPTION
29+
*
30+
* This file defines some array schema test suite helper functions.
31+
*/
32+
33+
#include "test/support/src/array_schema_helpers.h"
34+
#include "tiledb/api/c_api/enumeration/enumeration_api_internal.h"
35+
#include "tiledb/sm/array_schema/enumeration.h"
36+
#include "tiledb/sm/cpp_api/tiledb"
37+
38+
using namespace tiledb;
39+
40+
namespace tiledb::test {
41+
42+
bool is_equivalent_enumeration(
43+
const Enumeration& left, const Enumeration& right) {
44+
return left.name() == right.name() && left.type() == right.type() &&
45+
left.cell_val_num() == right.cell_val_num() &&
46+
left.ordered() == right.ordered() &&
47+
std::equal(
48+
left.ptr()->data().begin(),
49+
left.ptr()->data().end(),
50+
right.ptr()->data().begin(),
51+
right.ptr()->data().end());
52+
}
53+
54+
} // namespace tiledb::test
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @file array_schema_helpers.h
3+
*
4+
* @section LICENSE
5+
*
6+
* The MIT License
7+
*
8+
* @copyright Copyright (c) 2017-2024 TileDB, Inc.
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* in the Software without restriction, including without limitation the rights
13+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
* copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in
18+
* all copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26+
* THE SOFTWARE.
27+
*
28+
* @section DESCRIPTION
29+
*
30+
* This file declares some array schema test suite helper functions.
31+
*/
32+
33+
#ifndef TILEDB_TEST_ARRAY_SCHEMA_HELPERS_H
34+
#define TILEDB_TEST_ARRAY_SCHEMA_HELPERS_H
35+
36+
#include "tiledb/sm/cpp_api/tiledb"
37+
#include "tiledb/sm/cpp_api/tiledb_experimental"
38+
39+
namespace tiledb::test {
40+
41+
/**
42+
* @return if two enumerations `left` and `right` are equivalent,
43+
* i.e. have the same name, datatype, variants, etc
44+
*/
45+
bool is_equivalent_enumeration(
46+
const tiledb::Enumeration& left, const tiledb::Enumeration& right);
47+
48+
} // namespace tiledb::test
49+
50+
#endif

tiledb/api/c_api/array/test/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ commence(unit_test capi_array)
3131
this_target_object_libraries(
3232
capi_array_stub
3333
capi_array_schema_stub
34-
capi_attribute_stub
3534
capi_domain_stub
3635
)
3736
this_target_link_libraries(tiledb_test_support_lib)

tiledb/api/c_api/array_schema/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ commence(object_library capi_array_schema_stub)
3636
this_target_sources(${SOURCES})
3737
this_target_link_libraries(export)
3838
this_target_object_libraries(array_schema)
39+
this_target_object_libraries(array)
40+
this_target_object_libraries(capi_attribute_stub)
3941
this_target_object_libraries(capi_context_stub)
4042
conclude(object_library)
4143

tiledb/api/c_api/array_schema/array_schema_api.cc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "array_schema_api_experimental.h"
3535
#include "array_schema_api_internal.h"
3636

37+
#include "tiledb/api/c_api/attribute/attribute_api_external_experimental.h"
3738
#include "tiledb/api/c_api/attribute/attribute_api_internal.h"
3839
#include "tiledb/api/c_api/context/context_api_internal.h"
3940
#include "tiledb/api/c_api/current_domain/current_domain_api_external_experimental.h"
@@ -181,6 +182,54 @@ capi_return_t tiledb_array_schema_timestamp_range(
181182
return TILEDB_OK;
182183
}
183184

185+
capi_return_t tiledb_array_schema_get_enumeration_from_name(
186+
tiledb_ctx_t* ctx,
187+
tiledb_array_schema_t* array_schema,
188+
const char* enumeration_name,
189+
tiledb_enumeration_t** enumeration) {
190+
ensure_array_schema_is_valid(array_schema);
191+
ensure_output_pointer_is_valid(enumeration);
192+
193+
if (enumeration_name == nullptr) {
194+
throw CAPIException("'enumeration_name' must not be null");
195+
}
196+
197+
array_schema->load_enumeration(ctx, enumeration_name);
198+
199+
auto ptr = array_schema->get_enumeration(enumeration_name);
200+
*enumeration = tiledb_enumeration_handle_t::make_handle(ptr);
201+
202+
return TILEDB_OK;
203+
}
204+
205+
capi_return_t tiledb_array_schema_get_enumeration_from_attribute_name(
206+
tiledb_ctx_t* ctx,
207+
tiledb_array_schema_t* array_schema,
208+
const char* attribute_name,
209+
tiledb_enumeration_t** enumeration) {
210+
ensure_array_schema_is_valid(array_schema);
211+
ensure_output_pointer_is_valid(enumeration);
212+
213+
tiledb_attribute_t* attribute;
214+
capi_return_t getattr = tiledb_array_schema_get_attribute_from_name(
215+
ctx, array_schema, attribute_name, &attribute);
216+
if (tiledb_status(getattr) != TILEDB_OK) {
217+
return getattr;
218+
}
219+
220+
tiledb_string_t* enumeration_name_inner;
221+
capi_return_t getenmr = tiledb_attribute_get_enumeration_name(
222+
ctx, attribute, &enumeration_name_inner);
223+
if (tiledb_status(getenmr) != TILEDB_OK) {
224+
return getenmr;
225+
}
226+
227+
std::string enumeration_name(enumeration_name_inner->view());
228+
return api_entry_with_context<
229+
tiledb::api::tiledb_array_schema_get_enumeration_from_name>(
230+
ctx, array_schema, enumeration_name.c_str(), enumeration);
231+
}
232+
184233
capi_return_t tiledb_array_schema_add_enumeration(
185234
tiledb_array_schema_t* array_schema, tiledb_enumeration_t* enumeration) {
186235
ensure_array_schema_is_valid(array_schema);
@@ -365,6 +414,10 @@ capi_return_t tiledb_array_schema_get_attribute_from_name(
365414
ensure_array_schema_is_valid(array_schema);
366415
ensure_output_pointer_is_valid(attr);
367416

417+
if (name == nullptr) {
418+
throw CAPIException("'attribute_name' must not be null");
419+
}
420+
368421
uint32_t attribute_num = array_schema->attribute_num();
369422
if (attribute_num == 0) {
370423
*attr = nullptr;
@@ -540,6 +593,28 @@ CAPI_INTERFACE(
540593
ctx, array_schema, lo, hi);
541594
}
542595

596+
CAPI_INTERFACE(
597+
array_schema_get_enumeration_from_name,
598+
tiledb_ctx_t* ctx,
599+
tiledb_array_schema_t* array_schema,
600+
const char* enumeration_name,
601+
tiledb_enumeration_t** enumeration) {
602+
return api_entry_with_context<
603+
tiledb::api::tiledb_array_schema_get_enumeration_from_name>(
604+
ctx, array_schema, enumeration_name, enumeration);
605+
}
606+
607+
CAPI_INTERFACE(
608+
array_schema_get_enumeration_from_attribute_name,
609+
tiledb_ctx_t* ctx,
610+
tiledb_array_schema_t* array_schema,
611+
const char* attribute_name,
612+
tiledb_enumeration_t** enumeration) {
613+
return api_entry_with_context<
614+
tiledb::api::tiledb_array_schema_get_enumeration_from_attribute_name>(
615+
ctx, array_schema, attribute_name, enumeration);
616+
}
617+
543618
CAPI_INTERFACE(
544619
array_schema_add_enumeration,
545620
tiledb_ctx_t* ctx,

0 commit comments

Comments
 (0)