UDA 序列数据支持
为了支持序列类型的字段,mco_dict_field_info_t::flags 中接受三个标志:
#define MCO_DICT_FI_ASC_SEQUENCE 0x100
#define MCO_DICT_FI_DESC_SEQUENCE 0x200
#define MCO_DICT_FI_SEQUENCE 0x400如果字段类型被定义为序列,那么 mco_dict_field() 和 mco_dict_field_name() 函数会为其设置 MCO_DICT_FI_SEQUENCE 标志。如果序列是单调递增的,还会额外设置 MCO_DICT_FI_DESC_SEQUENCE 或 MCO_DICT_FI_ASC_SEQUENCE 标志。新的 mco_uda_seq_values_t 结构允许检索和更新序列元素:
typedef struct tag_mco_uda_seq_values_t_
{
mco_size_t size;
mco_dict_type_t elem_type;
uint2 elem_size; /* for MCO_DD_CHAR */
union
{
mco_uint1 *u1;
mco_uint2 *u2;
mco_uint4 *u4;
mco_uint8 *u8;
mco_int1 *i1;
mco_int2 *i2;
mco_int4 *i4;
mco_int8 *i8;
#ifdef MCO_TARGET_FLOAT_SUPPORTED
float *f;
double *d;
#endif
char *c;
} v;
} mco_uda_seq_values_t;这里的size是指结构 elem_type(序列元素类型)中的元素数量,该类型可以是以下几种之一:
MCO_DD_UINT1, MCO_DD_UINT2, MCO_DD_UINT4, MCO_DD_UINT8,
MCO_DD_INT1, MCO_DD_INT2, MCO_DD_INT4, MCO_DD_INT8,
MCO_DD_FLOAT, MCO_DD_DOUBLE or MCO_DD_CHAR请注意,elem_size(元素大小)仅在 elem_type(元素类型)等于 MCO_DD_CHAR 时才有意义。
unin元素 v 引用相应类型的数组(类型由 elem_type 定义)。这些数组必须由应用程序进行分配和释放。
可以调用 mco_uda_is_sequence() 函数来确定一个字段是否为序列类型:
mco_bool mco_uda_is_sequence(mco_dict_type_t type);如果字段被定义为序列类型(例如 MCO_DD_SEQUENCE_UINT1、MCO_DD_SEQUENCE_FLOAT 等),此函数将返回 MCO_YES。
序列函数
序列包装函数与 DDL 编译器为序列生成的函数相对应,例如:
MCO_RET mco_uda_seq_first(const mco_uda_object_handle_p obj,
unsigned short field_no,/*OUT*/
mco_uda_value_t *value);
MCO_RET mco_uda_seq_last(const mco_uda_object_handle_p obj,
unsigned short field_no,/*OUT*/
mco_uda_value_t *value);
MCO_RET mco_uda_seq_append(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_uda_seq_values_t *values);
MCO_RET mco_uda_seq_insert(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_no_t pos,
mco_uda_seq_values_t *values);
MCO_RET mco_uda_seq_delete(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_no_t from,
mco_seq_no_t till);
MCO_RET mco_uda_seq_count(const mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_no_t *count);
MCO_RET mco_uda_seq_search(const mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_iterator_h iterator,
const mco_uda_value_t *low,
mco_seq_boundary_kind_t low_boundary,
const mco_uda_value_t *high,
mco_seq_boundary_kind_t high_boundary);
MCO_RET mco_uda_seq_join(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_iterator_h result,
mco_seq_iterator_h join_with);
MCO_RET mco_uda_seq_obj_map(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_iterator_h dst_iterator,
mco_seq_iterator_h map_iterator);
MCO_RET mco_uda_seq_subseq(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_iterator_h iterator,
mco_seq_no_t from,
mco_seq_no_t till);
MCO_RET mco_uda_seq_iterator(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_iterator_h iterator);
MCO_RET mco_uda_seq_project(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_iterator_h dst,
mco_seq_iterator_h src);
MCO_RET mco_uda_seq_store(mco_uda_object_handle_p obj,
unsigned short field_no,
mco_seq_iterator_h src);
MCO_RET mco_uda_seq_truncate(const mco_uda_object_handle_p udaobj,
unsigned short field_no);每个 mco_uda_seq_<operation>(const mco_uda_object_handle_p obj, unsigned short field_no, ...) 函数都对应于生成的 <classname>_<fieldname>_<operation>(<classname> *obj, ...)。通用的 mco_uda_value_t 结构被用于替代类型感知参数。
例如,如果模式将一个序列字段定义为 sequence<float> ,那么
MCO_RET mco_uda_seq_first(
const mco_uda_object_handle_p obj,
unsigned short field_no,
/*OUT*/ mco_uda_value_t *value
);相似
MCO_RET Classname_fieldname_first(Classname *handle, float* val);命名约定的一个小例外是 <classname>_<fieldname>_map(...) 函数。它被命名为 mco_uda_seq_obj_map(...)。(这是为了避免与下面的迭代器 API 发生冲突。)
使用示例
以下代码片段演示了如何将一系列值附加到数据库对象中:
mco_uda_seq_values_t seqvals;
seqvals.elem_type = MCO_DD_UINT4;
seqvals.size = seq_size;
seqvals.v.u4 = malloc(sizeof(uint4) * seqvals.size);
for (i = 0; i < seqvals.size; ++i)
{
seqvals.v.u4[i] = <...>;
}
mco_uda_seq_append(&obj, timestamp_no, &seqvals);
free(seqvals.v.u4);迭代器 API
总体而言,UDA 定义了 mco_uda_seq_<operation>() 函数(例如 mco_uda_seq_add()),而不是元素的 mco_seq_<operation>_<type>(...) 函数(如 mco_seq_add_float()、mco_seq_add_uint1() 等)。请注意,<type> 的值根据元素的类型(如果可能的话)确定。使用 mco_uda_value_t 替代特定类型的参数。例如,替代以下函数
MCO_RET mco_seq_next_uint1(mco_seq_iterator_h iterator, uint1 *val);UDA API 定义了
MCO_RET mco_uda_seq_next(mco_seq_iterator_h iterator, mco_uda_value_t* uda_val);后一个函数将 MCO_DD_UINT1 分配给 uda_val,并返回 uda_val->v.u1 中的元素; 同样,UDA API 不使用特定类型的值数组,而是使用通用的 mco_uda_seq_values_t 结构。例如,不是使用
MCO_RET mco_seq_get_float(mco_seq_iterator_h input, float *result, mco_size_t *size);而是使用
MCO_RET mco_uda_seq_get(mco_seq_iterator_h input, mco_uda_seq_values_t *values);values.size 参数取代了 size,而 values.v.f 则是结果。 总体而言,UDA API 包含了一百多个不同的函数。整个列表可以在文件 include/mcouda.h 中找到。
示例使用2
以下示例代码将两个序列中的值相加:
mco_seq_iterator_t result, it1, it2, cast_it2;
mco_uda_seq_iterator(&obj, field1_no, &it1); // get iterator for object's field field1
mco_uda_seq_iterator(&obj, field2_no, &it2); // get iterator for object's field field2
mco_uda_seq_cast(&cast_it2, it1.elem_type, &it2); // cast elements from field2 to field1's type
mco_uda_seq_add(&result, &it1, &cast_it2); // add elements of field1 and field2