如何从 boost::mysql::row 获取元数据?
How can I get metadata from boost::mysql::row?
如何将元数据从元素获取到 boost::mysql::row?
void print_employee(const boost::mysql::row& employee)
{
std::cout << "Employee '"
<< employee.values()[0] << std::endl;
我如何从这里获取元数据?我想提取这个特定值的列名
const boost::mysql::field_metadata &column = employee[0];
std::cout << column.original_field_name() << std::endl;
}
std::vector<boost::mysql::row> employees = result.read_all();
for (const auto& employee: employees)
{
print_employee(employee);
}
与此文档相关:https://anarthal.github.io/mysql/mysql/resultsets.html#mysql.resultsets.metadata
而这个 https://anarthal.github.io/mysql/
问题是 boost::mysql::row 中没有 属性 original_field_name 和其他因为它们在 ::field_metadata.
知道怎么连接子类2就好了。
肯定有办法,只是没找到
字段元数据描述了一个行集,而不是单个行(因为在 SQL 模型中,结果集中的每一行都具有完全相同的元数据)。
因此,假设您有一个名为 Test 的数据库,其中包含一条 table 消息,您可以使用每一行的元数据,如下所示:
#include <boost/mysql.hpp>
#include <iostream>
using boost::asio::ip::tcp;
int main()
{
boost::asio::io_context ctx;
boost::mysql::tcp_connection conn(ctx);
boost::mysql::connection_params params("su", "su", "Test");
conn.connect(tcp::endpoint{{}, boost::mysql::default_port}, params);
auto rs = conn.query("SELECT * FROM Message;");
std::vector<boost::mysql::field_metadata> const& meta = rs.fields();
for (auto&& r : rs.read_all()) {
std::cout << " ---- row:\n";
std::vector<boost::mysql::value> const& v = r.values();
for (size_t i = 0; i < meta.size(); ++i) {
std::cout << "\tcol:" << meta[i].original_field_name() << " val:" << v[i] << "\n";;
}
}
}
在我的系统上,打印出类似
的内容
---- row:
col:message_id val:165
col:login_sender_id val:1
col:login_recipient_id val:2
col:date val:2021-02-01 02:24:22.000000
col:content val:ahoi
col:dialog_id val:1
col:read_by_recipient val:1
---- row:
col:message_id val:166
col:login_sender_id val:2
col:login_recipient_id val:1
col:date val:2021-02-01 02:24:25.000000
col:content val:bye
col:dialog_id val:1
col:read_by_recipient val:1
---- row:
...
etc.
更优雅
一些明智的 usings/auto 它变得不那么麻烦:
#include <boost/mysql.hpp>
#include <iostream>
using boost::asio::ip::tcp;
using boost::mysql::tcp_connection;
int main()
{
boost::asio::io_context ctx;
tcp_connection conn(ctx);
conn.connect(tcp::endpoint{{}, boost::mysql::default_port}, {"su", "su", "Test"});
auto rs = conn.query("SELECT * FROM Message;");
auto& meta = rs.fields();
for (auto&& r : rs.read_all()) {
std::cout << " ---- row:\n";
auto& v = r.values();
for (size_t i = 0; i < meta.size(); ++i) {
std::cout << "\tcol:" << meta[i].original_field_name() << " val:" << v[i] << "\n";;
}
}
}
樱桃在上面
为了减少使用整数索引的麻烦,您可以在视图中隐藏所有内容:
auto meta_view(resultset& rs) {
auto all = std::make_shared<std::vector<row> >(rs.read_all());
auto row_view = [meta = rs.fields(), all](row const& r) {
return std::views::iota(0ul, meta.size()) |
std::views::transform([&](size_t idx) {
return std::tie(r.values()[idx], meta[idx]);
});
};
return *all | std::views::transform(row_view);
}
Note, this plays tricks to solve issues with lifetime and the result is not very efficient. So, maybe just accept the crummy-ness of the interface and take this example as inspiration for other things
现在客户端代码可以
auto rs = conn.query("SELECT * FROM Message;");
for (auto&& r : meta_view(rs)) {
std::cout << " ---- row:\n";
for (auto&& [val, meta] : r) {
std::cout << "\tcol:" << meta.original_field_name()
<< " val:" << val << "\n";
}
}
仍在打印相同的输出。 (std::ranges 需要 c++20)
如何将元数据从元素获取到 boost::mysql::row?
void print_employee(const boost::mysql::row& employee)
{
std::cout << "Employee '"
<< employee.values()[0] << std::endl;
我如何从这里获取元数据?我想提取这个特定值的列名
const boost::mysql::field_metadata &column = employee[0];
std::cout << column.original_field_name() << std::endl;
}
std::vector<boost::mysql::row> employees = result.read_all();
for (const auto& employee: employees)
{
print_employee(employee);
}
与此文档相关:https://anarthal.github.io/mysql/mysql/resultsets.html#mysql.resultsets.metadata 而这个 https://anarthal.github.io/mysql/
问题是 boost::mysql::row 中没有 属性 original_field_name 和其他因为它们在 ::field_metadata.
知道怎么连接子类2就好了。 肯定有办法,只是没找到
字段元数据描述了一个行集,而不是单个行(因为在 SQL 模型中,结果集中的每一行都具有完全相同的元数据)。
因此,假设您有一个名为 Test 的数据库,其中包含一条 table 消息,您可以使用每一行的元数据,如下所示:
#include <boost/mysql.hpp>
#include <iostream>
using boost::asio::ip::tcp;
int main()
{
boost::asio::io_context ctx;
boost::mysql::tcp_connection conn(ctx);
boost::mysql::connection_params params("su", "su", "Test");
conn.connect(tcp::endpoint{{}, boost::mysql::default_port}, params);
auto rs = conn.query("SELECT * FROM Message;");
std::vector<boost::mysql::field_metadata> const& meta = rs.fields();
for (auto&& r : rs.read_all()) {
std::cout << " ---- row:\n";
std::vector<boost::mysql::value> const& v = r.values();
for (size_t i = 0; i < meta.size(); ++i) {
std::cout << "\tcol:" << meta[i].original_field_name() << " val:" << v[i] << "\n";;
}
}
}
在我的系统上,打印出类似
的内容 ---- row:
col:message_id val:165
col:login_sender_id val:1
col:login_recipient_id val:2
col:date val:2021-02-01 02:24:22.000000
col:content val:ahoi
col:dialog_id val:1
col:read_by_recipient val:1
---- row:
col:message_id val:166
col:login_sender_id val:2
col:login_recipient_id val:1
col:date val:2021-02-01 02:24:25.000000
col:content val:bye
col:dialog_id val:1
col:read_by_recipient val:1
---- row:
...
etc.
更优雅
一些明智的 usings/auto 它变得不那么麻烦:
#include <boost/mysql.hpp>
#include <iostream>
using boost::asio::ip::tcp;
using boost::mysql::tcp_connection;
int main()
{
boost::asio::io_context ctx;
tcp_connection conn(ctx);
conn.connect(tcp::endpoint{{}, boost::mysql::default_port}, {"su", "su", "Test"});
auto rs = conn.query("SELECT * FROM Message;");
auto& meta = rs.fields();
for (auto&& r : rs.read_all()) {
std::cout << " ---- row:\n";
auto& v = r.values();
for (size_t i = 0; i < meta.size(); ++i) {
std::cout << "\tcol:" << meta[i].original_field_name() << " val:" << v[i] << "\n";;
}
}
}
樱桃在上面
为了减少使用整数索引的麻烦,您可以在视图中隐藏所有内容:
auto meta_view(resultset& rs) {
auto all = std::make_shared<std::vector<row> >(rs.read_all());
auto row_view = [meta = rs.fields(), all](row const& r) {
return std::views::iota(0ul, meta.size()) |
std::views::transform([&](size_t idx) {
return std::tie(r.values()[idx], meta[idx]);
});
};
return *all | std::views::transform(row_view);
}
Note, this plays tricks to solve issues with lifetime and the result is not very efficient. So, maybe just accept the crummy-ness of the interface and take this example as inspiration for other things
现在客户端代码可以
auto rs = conn.query("SELECT * FROM Message;");
for (auto&& r : meta_view(rs)) {
std::cout << " ---- row:\n";
for (auto&& [val, meta] : r) {
std::cout << "\tcol:" << meta.original_field_name()
<< " val:" << val << "\n";
}
}
仍在打印相同的输出。 (std::ranges 需要 c++20)