PostgreSQL C++(pqxx)和设置值(如果不是NULL)



我有一些代码如下所示:

for (const auto& query_result_row : query_result) {
my_struct.a = query_results_row["a"].as<int>();
my_struct.b = query_results_row["b"].as<string>();
// and so forth.
}

一般来说,可能存在许多不同类型的字段。这很好,但如果所选字段为NULL,则会引发异常。因此,我现在写了这篇文章,它非常尴尬,而且有点容易出错:

for (const auto& query_result_row : query_result) {
if (!query_results_row["a"].is_null()) {
my_struct.a = query_results_row["a"].as<int>();
}
if (!query_results_row["ab"].is_null()) {
my_struct.b = query_results_row["b"].as<string>();
}
// and so forth.
}

Ick。

也许,我想,我可以制作一个(模板化的(函数来简化这一点:

for (const auto& query_result_row : query_result) {
MaybeSet(my_struct.a, query_results_row["a"]);
MaybeSet(my_struct.b, query_results_row["b"]);
// and so forth.
}

这里的问题是,query_results_row["a"]本身就是一个模板化类型,而且,as()类型可能与my_struct类型不完全相同(例如,不同类型的int(,尽管我今天没有看到它,但闻起来像是有一天可能会导致意外的强制转换。

// Doesn't work.
template <typename valueT, typename postgresFieldT>
void MaybeSet(valueT& my_struct_field, const postgresFieldT& field) {
if (!field.is_null()) {
my_struct_field = field.as<valueT>();
}
}

有什么建议可以用一种更干净的方式来表达这种想法,即如果它们不是空的,就设置它们,如果它们是空的,则不尝试?

对于子孙后代:我稍微改变了这个问题,因此得出了一个简单的解决方案。

template <typename T>
class SetThing {
// ...
void MaybeSet(const pqxx::result::field& field) {
if (!field.is_null()) {
SetClean(field.as<T>());
}
}
template <typename asT>
void MaybeSet(const pqxx::result::field& field) {
if (!field.is_null()) {
SetClean(field.as<asT>());
}
}
// ...
}

然后使用成为

SetThing thing;
thing.MaybeSet(query_result_row["dog"]);
thing.MaybeSet<the_cast_type>(query_result_row["complicated"]);

第二种形式用于少数复杂类型(例如类(,我可以从简单的东西(比如int或字符串(构造这些类型,但它们不是SetThing的基(模板化(类型。

相关内容

  • 没有找到相关文章

最新更新