Ваши строки не являются стандартными. Вероятно, 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"
И таблица содержит
NOTES
In the sample there appears to be a memory leak when the insert statements throw. I guess this need to be reported upstream.
THINK TWICE before storing passwords in a database. Proper security rules of thumb:
- Never store passwords. Period.
- Always store hashes
- Do NOT use fast hashes or non-cryptographically strong hashes (no MD5 or SHA bullshit, use PKDBF2, scrypt или аналогичный )
- Всегда используйте для каждого пользователя salt