使用序列数据
序列数据是支持标量数据元素的无界数组。在 C++ 应用程序中,Sequence 类与生成的 C API 的 classname_fieldname_*()
函数一起使用,以管理类型为序列的数据库字段,并通过迭代器来访问。
在 C 应用程序中,使用 C 类型 mco_seq_iterator_h,而在 C++ 应用程序中则使用 C++ 类 Sequence 来发挥相同的作用。Sequence 类提供了一组强大的分析方法,用于对序列执行数学和统计操作。
插入和更新序列
通常情况下,序列数据是通过生成的 C API 的 classname_fieldname_append()
函数插入的。
例如:
#define uint4 unsigned<4>
class Quote {
char<16> symbol;
sequence<uint4 asc> day;
sequence<float> price;
tree<symbol> by_symbol;
};
通过这个类定义,Quote 序列字段 day 和 price 就可以用如下代码进行填充:
#define N_ITEMS 4
uint4 days[N_ITEMS] = { 1, 2, 4, 5 };
float prices[N_ITEMS] = { 10, 20, 40 ,50 };
...
Quote q;
q.create(t);
q.symbol_put("IBM", (uint2)(strlen("IBM")));
q.day_append(days, N_ITEMS);
...
q.price_append(prices, N_ITEMS);
有时可能需要向有序的时间序列中插入值。可以使用生成的 C API <classname><fieldname>insert()
将值插入到现有序列中。
例如,以下代码片段会搜索具有“IBM”符号的 Quote 对象,然后插入日期和价格值:
#define DAY_THREE 3
#define DAY_THREE_PRICE 30
uint4 day_to_insert[1] = { DAY_THREE };
float price_to_insert[1] = { DAY_THREE_PRICE };
...
mco_trans_h t;
mco_cursor_t cur;
...
mco_trans_start(db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t);
mco_cursor_first(t, &cur);
rc = Quote::by_symbol::cursor(t, &cur);
if (MCO_S_OK == rc)
{
rc = Quote::by_symbol::search(t, &cur, MCO_GE, "IBM",
(uint2)(sizeof("IBM")));
if (MCO_S_OK == rc)
{
//插入
Quote q;
q.create(t);
rc = q.from_cursor(t, &cur);
Sequence<uint4> seq = q.day_iterator();
if (MCO_S_OK == rc)
{
rc = q.day_search(seq,
DAY_THREE, MCO_SEQ_BOUNDARY_EXCLUSIVE,
0, MCO_SEQ_BOUNDARY_OPEN);
mco_seq_no_t pos = seq.iter->first_seq_no;
rc = q.day_insert(pos, day_to_insert, 1);
...
rc = q.price_insert(pos, price_to_insert, 1);
rc = mco_trans_commit(t);
}
}
}
迭代序列
通常,序列数据是通过 Sequence 方法 next() 来迭代的。例如,Quote 序列字段 day 和 price 可以通过如下代码进行迭代:
mco_trans_h trans;
MCO_RET rc;
...
mco_trans_start(db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &trans);
if ( MCO_S_OK == rc )
{
Sequence<uint4> day_iterator;
...
quote.day_search(day_iterator, DMY(1,1,2013), MCO_SEQ_BOUNDARY_INCLUSIVE, DMY(1,4,2013), MCO_SEQ_BOUNDARY_INCLUSIVE));
Sequence<float> price_iterator = quote.price_project(day_iterator);
/* 迭代日期和价格序列 */
while (day_iterator.next(day))
{
printf("%u: %f\n", day, ++price_iterator);
}
mco_trans_rollback(trans);
}
这里使用了 next()
方法来遍历日期序列,同时使用了方便的 ++
运算符来遍历价格序列。
运用分析方法
如上所述,Sequence 类提供了许多分析方法,可高效地处理序列数据并执行各种统计操作。
例如,以下代码片段演示了如何使用通用序列输出函数 print_sequence()
迭代报价价格值的网格聚合最大值序列。
可参阅 SDK 示例 samples/native/sequences/api/cpp 中所示:
mco_trans_h trans;
MCO_RET rc;
...
mco_trans_start(db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &trans);
if ( MCO_S_OK == rc )
{
/* 遍历所有报价对象 */
Quote::by_sym::cursor(trans, "e_cursor);
for (rc = mco_cursor_first(trans, "e_cursor);
rc != MCO_S_CURSOR_END;
rc = mco_cursor_next(trans, "e_cursor))
{
/* 获取当前的报价对象 */
quote.from_cursor(trans, "e_cursor);
/* 打印价格的网格聚合序列 */
print_sequence(quote, quote.price_iterator().gridAggMax(7));
}
mco_trans_rollback(trans);
}
请注意,由生成的函数 quote.price_iterator()
返回的 C 类型序列迭代器会被转换为 C++ 序列,并在其对函数 print_sequence()
的调用中调用其方法 gridAggMax()
。然后在 print_sequence()
中对该序列进行迭代并打印出来。