|
|
@@ -52,6 +52,36 @@ bool checkAnyType(const std::any& value)
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+/// <summary>
|
|
|
+/// 入库前规范化 std::any:const char*/char* 立刻拷成 std::string,避免存指针到 exec 时悬空。
|
|
|
+/// </summary>
|
|
|
+static std::any normalize_sql_any(const std::any& value)
|
|
|
+{
|
|
|
+ if (!value.has_value()) {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ if (value.type() == typeid(const char*)) {
|
|
|
+ const char* p = std::any_cast<const char*>(value);
|
|
|
+ return std::string(p != nullptr ? p : "");
|
|
|
+ }
|
|
|
+ if (value.type() == typeid(char*)) {
|
|
|
+ char* p = std::any_cast<char*>(value);
|
|
|
+ return std::string(p != nullptr ? p : "");
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+}
|
|
|
+
|
|
|
+static std::vector<std::any> normalize_sql_any_list(const std::vector<std::any>& values)
|
|
|
+{
|
|
|
+ std::vector<std::any> out;
|
|
|
+ out.reserve(values.size());
|
|
|
+ for (size_t i = 0; i < values.size(); ++i) {
|
|
|
+ out.push_back(normalize_sql_any(values[i]));
|
|
|
+ }
|
|
|
+ return out;
|
|
|
+}
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 置入插入数据
|
|
|
/// </summary>
|
|
|
@@ -60,6 +90,12 @@ bool checkAnyType(const std::any& value)
|
|
|
/// <param name="value"></param>
|
|
|
void setInsetValue(mysql::prepare_statement*ppst, uint32 index, const std::any& value)
|
|
|
{
|
|
|
+ // 防御:若仍有指针(绕过 set/where 规范化),按字符串绑定
|
|
|
+ if (value.type() == typeid(const char*) || value.type() == typeid(char*)) {
|
|
|
+ std::any as_str = normalize_sql_any(value);
|
|
|
+ ppst->set_string(index, std::any_cast<std::string>(as_str));
|
|
|
+ return;
|
|
|
+ }
|
|
|
if (value.type() == typeid(int32)) {
|
|
|
ppst->set_int32(index,std::any_cast<int32>(value));
|
|
|
}
|
|
|
@@ -108,21 +144,24 @@ static void check_where_values(const std::vector<std::any>& values)
|
|
|
|
|
|
static ylib::where make_where_in(const std::string& name, const std::vector<std::any>& values, bool not_in)
|
|
|
{
|
|
|
- check_where_values(values);
|
|
|
+ std::vector<std::any> normalized = normalize_sql_any_list(values);
|
|
|
+ check_where_values(normalized);
|
|
|
ylib::where w;
|
|
|
w.name = name;
|
|
|
- w.values = values;
|
|
|
+ w.values = std::move(normalized);
|
|
|
w.type = not_in ? 7 : 6;
|
|
|
return w;
|
|
|
}
|
|
|
|
|
|
static ylib::where make_where_between(const std::string& name, const std::any& begin, const std::any& end, bool not_between)
|
|
|
{
|
|
|
- check_where_value(begin);
|
|
|
- check_where_value(end);
|
|
|
+ std::any b = normalize_sql_any(begin);
|
|
|
+ std::any e = normalize_sql_any(end);
|
|
|
+ check_where_value(b);
|
|
|
+ check_where_value(e);
|
|
|
ylib::where w;
|
|
|
w.name = name;
|
|
|
- w.values = { begin, end };
|
|
|
+ w.values = { b, e };
|
|
|
w.type = not_between ? 9 : 8;
|
|
|
return w;
|
|
|
}
|
|
|
@@ -269,7 +308,7 @@ ylib::select& ylib::select::where(const std::string& name, const std::string& ex
|
|
|
ylib::where w;
|
|
|
w.name = name;
|
|
|
w.expression = expression;
|
|
|
- w.value = value;
|
|
|
+ w.value = normalize_sql_any(value);
|
|
|
w.type = 0;
|
|
|
if (w.value.has_value() == false)
|
|
|
{
|
|
|
@@ -494,7 +533,7 @@ ylib::update& ylib::update::set(const std::string& name, const std::any& value)
|
|
|
struct update::set s;
|
|
|
s.type = 0;
|
|
|
s.name = name;
|
|
|
- s.value = value;
|
|
|
+ s.value = normalize_sql_any(value);
|
|
|
m_sets.push_back(s);
|
|
|
return *this;
|
|
|
}
|
|
|
@@ -513,7 +552,7 @@ ylib::update& ylib::update::where(const std::string& name, const std::string& ex
|
|
|
ylib::where w;
|
|
|
w.name = name;
|
|
|
w.expression = expression;
|
|
|
- w.value = value;
|
|
|
+ w.value = normalize_sql_any(value);
|
|
|
w.type = 0;
|
|
|
if (w.value.has_value() == false)
|
|
|
{
|
|
|
@@ -705,7 +744,7 @@ ylib::insert& ylib::insert::table(const std::string& table_name)
|
|
|
|
|
|
ylib::insert& ylib::insert::set(const std::string& name, const std::any& value)
|
|
|
{
|
|
|
- m_sets.push_back({name, value});
|
|
|
+ m_sets.push_back({name, normalize_sql_any(value)});
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
@@ -788,7 +827,7 @@ ylib::delete_& ylib::delete_::where(const std::string& name, const std::string&
|
|
|
ylib::where w;
|
|
|
w.name = name;
|
|
|
w.expression = expression;
|
|
|
- w.value = value;
|
|
|
+ w.value = normalize_sql_any(value);
|
|
|
w.type = 0;
|
|
|
if (w.value.has_value() == false)
|
|
|
{
|