gpt4 book ai didi

c++ - 如何绑定(bind) SOCI 查询的输出?

转载 作者:行者123 更新时间:2023-12-02 10:29:40 26 4
gpt4 key购买 nike

以下代码:生成错误消息,如下:

bool UACmUsers::GetUser(int userid) {
soci::session sql(dbU::Connection());
sql << "SELECT userid, username, password FROM uac_users WHERE userid = \":user\"",
soci::use(userid),
soci::into(iDuserid, indUserid),
soci::into(sDusername, indUsername), // This is line 61.
soci::into(sDpassword, indPassword);

return true;
}
dbU::Connection()是一个生成连接字符串的函数。 iDuserid , sDusername , 和 sDpassword是 UACmUsers 的私有(private)成员,类型为 intstd::string . indUserid , indUsername , 和 indPassword是 UACmUsers 的私有(private)成员,类型为 soci::indicator .
有第二个重载函数搜索 username。 .如果我注释掉这个函数,只剩下第二个,编译器指向第二个函数中的同一点。 bool UACmUsers::GetUser(const wxString& username);我已经尝试删除两个指标,但这并不能解决问题。
错误:
E:\cpp\lib\soci\soci-4.0.0\include\soci/exchange-traits.h(41): error C2065: 'x_type': undeclared identifier
E:\cpp\lib\soci\soci-4.0.0\include\soci/bind-values.h(207): note: see reference to class template instantiation 'soci::details::exchange_traits<T>' being compiled
with
[
T=wxString
]
E:\cpp\lib\soci\soci-4.0.0\include\soci/bind-values.h(143): note: see reference to function template instantiation 'void soci::details::into_type_vector::exchange_<wxString,soci::indicator>(const soci::details::into_container<wxString,soci::indicator> &,...)' being compiled
E:\cpp\lib\soci\soci-4.0.0\include\soci/statement.h(50): note: see reference to function template instantiation 'void soci::details::into_type_vector::exchange<wxString,soci::indicator>(const soci::details::into_container<wxString,soci::indicator> &)' being compiled
E:\cpp\lib\soci\soci-4.0.0\include\soci/statement.h(199): note: see reference to function template instantiation 'void soci::details::statement_impl::exchange<wxString,soci::indicator>(const soci::details::into_container<wxString,soci::indicator> &)' being compiled
E:\cpp\lib\soci\soci-4.0.0\include\soci/ref-counted-statement.h(92): note: see reference to function template instantiation 'void soci::statement::exchange<wxString,soci::indicator>(const soci::details::into_container<wxString,soci::indicator> &)' being compiled
E:\cpp\lib\soci\soci-4.0.0\include\soci/once-temp-type.h(49): note: see reference to function template instantiation 'void soci::details::ref_counted_statement::exchange<const soci::details::into_container<wxString,soci::indicator>>(T &)' being compiled
with
[
T=const soci::details::into_container<wxString,soci::indicator>
]
E:\cpp\dev\Manager\src\UAC\models\UACmUsers.cpp(61): note: see reference to function template instantiation 'soci::details::once_temp_type &soci::details::once_temp_type::operator ,<wxString,soci::indicator>(const soci::details::into_container<wxString,soci::indicator> &)' being compiled
有人可以帮我让 SOCI 表现得更好吗?

这是 GitHub 上一个项目的一部分.链接到 headersource包含上述代码的文件。

最佳答案

您的字符串不是标准字符串。 wxString 在 SOCI 中可能没有转换支持。
要么进行转换,要么扩展类型转换。也许不是最有效但有效:

namespace soci {
template <> struct type_conversion<wxString> {
typedef std::string base_type;

static void from_base(base_type const& s, indicator ind, wxString& ws) {
if (ind == i_null)
ws.clear();
else
ws = s;
}

static void to_base(const wxString& ws, base_type& s, indicator& ind) {
s = ws.ToStdString();
ind = i_ok;
}
};
} // namespace soci
完整演示
#include <iomanip>
#include <iostream>
#include <soci/boost-tuple.h>
#include <soci/mysql/soci-mysql.h>
#include <soci/soci.h>
#include <soci/use.h>
#include <wx/string.h>

namespace soci {
template <> struct type_conversion<wxString> {
typedef std::string base_type;

static void from_base(base_type const& s, indicator ind, wxString& ws) {
if (ind == i_null)
ws.clear();
else
ws = s;
}

static void to_base(const wxString& ws, base_type& s, indicator& ind) {
s = ws.ToStdString();
ind = i_ok;
}
};
} // namespace soci

using namespace std::string_literals;

namespace dbU {
static soci::connection_parameters
parms("mysql://db=test user=root password='root'");

auto Connection() { return soci::session(parms); }

void setup() {
try {
dbU::Connection()
.create_table("uac_users")
.column("userid", soci::data_type::dt_integer)
.primary_key("userid", "userid")
.column("username", soci::data_type::dt_string)
.column("password", soci::data_type::dt_string);
} catch (soci::mysql_soci_error const& e) {
std::cout << "Table already exists\n";
}

{
using Rec = boost::tuple<int, std::string, std::string>;
Rec rec;

auto db = dbU::Connection();
soci::statement st =
(db.prepare << "insert into uac_users values (:id, :name, :pwd)",
soci::use(rec));

for (auto vals : { Rec
{ 11, "one"s, "bar"s },
{ 12, "two"s, "gjb"s },
{ 13, "three"s, "guerr"s },
{ 14, "four"s, "sbhe"s },
{ 15, "five"s, "svir"s }, })
{
try {
rec = vals;
st.execute(true);
} catch (soci::mysql_soci_error const& e) {
std::cout << e.what() << "\n";
}
}
}
}
} // namespace dbU

struct X {
int iDuserid;
wxString sDusername, sDpassword;
soci::indicator indUserid, indUsername, indPassword;

bool foo(int userid) {
soci::session sql(dbU::Connection());

sql << R"(SELECT userid, username, password FROM uac_users WHERE userid = ":user")",
soci::use(userid), soci::into(iDuserid, indUserid),
soci::into(sDusername, indUsername), // This is line 27
soci::into(sDpassword, indPassword);

std::cout << "last: " << sql.get_last_query() << "\n";

return true;
}
};

int main() {
dbU::setup();

X x;
x.foo(12);

std::cout << x.iDuserid << " " << std::quoted(x.sDusername.ToStdString())
<< " " << std::quoted(x.sDpassword.ToStdString()) << "\n";
}
打印
last: SELECT userid, username, password FROM uac_users WHERE userid = ":user"
12 "two" "gjb"
或者在随后的运行中:
Table already exists                                
Duplicate entry '11' for key 'PRIMARY' while executing "insert into uac_users values (:id, :name, :pwd)" with :id=11, :name="one", :pwd="bar".
Duplicate entry '12' for key 'PRIMARY' while executing "insert into uac_users values (:id, :name, :pwd)" with :id=12, :name="two", :pwd="gjb".
Duplicate entry '13' for key 'PRIMARY' while executing "insert into uac_users values (:id, :name, :pwd)" with :id=13, :name="three", :pwd="guerr".
Duplicate entry '14' for key 'PRIMARY' while executing "insert into uac_users values (:id, :name, :pwd)" with :id=14, :name="four", :pwd="sbhe".
Duplicate entry '15' for key 'PRIMARY' while executing "insert into uac_users values (:id, :name, :pwd)" with :id=15, :name="five", :pwd="svir".
last: SELECT userid, username, password FROM uac_users WHERE userid = ":user"
12 "two" "gjb"
该表包含
enter image description here
笔记
在示例中,当插入语句抛出时,似乎存在内存泄漏。我想这需要在上游报告。
在将密码存储到数据库之前三思而后行。适当的安全经验法则:
  • 永远不要存储密码。时期。
  • 始终存储哈希
  • 不要使用快速散列或非加密强散列(没有 MD5 或 SHA 废话,使用 PKDBF2, scrypt or similar)
  • 始终使用每个用户 salt
  • 关于c++ - 如何绑定(bind) SOCI 查询的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62825958/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com