C++如何创建"绑定"字符串文本替换方法?
C++ how to create 'bind' string text replacement method?
所以我看一下sqlite3cpp wiki。他们有一个很好的API:
sqlite3pp::command cmd(db, "INSERT INTO contacts (name, phone) VALUES (:user, :phone)");
cmd.bind(":user", "Mike");
cmd.bind(":phone", "555-1234");
cmd.execute();
我想知道如何使用boost来创建类似于常规std::string的API ?意思是像
std::string str = "INSERT INTO contacts (name, phone) VALUES (:user, :phone)";
bind(str, ":user", "Mike");
bind(str, ":phone", "555-1234");
有可能用boost创建这样的东西吗?怎么做?
可能:boost::algorithm::replace_all
?或者boost::algorithm::replace_all_copy
,如果你不想修改原始字符串
替换字符串很容易,但要执行类型安全的操作并很好地转换SQL,则略有不同。我们需要一个绑定器类,它可以根据传递的类型进行绑定,并进行任何必要的转换。
首先,我们需要包装std::type_info
,以便它可以在哈希映射中使用:
class typeInfoWrapper
{
friend bool operator == (const typeInfoWrapper& l, const typeInfoWrapper& r);
private:
const std::type_info& typeInfo_;
public:
typeInfoWrapper(const std::type_info& info) : typeInfo_(info) { };
// hasher
class hash
{
public:
size_t operator()(const typeInfoWrapper& typeInfo) const
{
return typeInfo.typeInfo_.hash_code();
};
}; // eo class hash
}; // eo class typeInfoWrapper
bool operator == (const typeInfoWrapper& l, const typeInfoWrapper& r)
{
return l.typeInfo_.hash_code() == r.typeInfo_.hash_code();
} // eo operator ==
接下来,我们需要类本身。这里我用的是c++ 11,所以我要用lambda。对于我们注册的每种类型,我们将注册一个函数,该函数接受字符串并以适合SQL的格式返回字符串。在本例中,我分别为字符串和int类型注册了一个。字符串一个只是用''
替换'
,并返回引号本身。int类型只返回自身,不需要对SQL进行解析。
class binder
{
private:
typedef std::function<std::string(std::string&)> ReplaceFunc;
typedef std::tr1::unordered_map<typeInfoWrapper, ReplaceFunc, typeInfoWrapper::hash> ReplaceMap;
typedef std::pair<typeInfoWrapper, ReplaceFunc> ReplacePair;
ReplaceMap typeMap_;
public:
binder()
{
// add string and int for test purposes
typeMap_.insert(ReplacePair(typeid(const char*), [](std::string& data) -> std::string
{
// escape the "'" to prevent SQL injection
boost::replace_all(data, "'", "''");
return "'" + data + "'";
}));
typeMap_.insert(ReplacePair(typeid(int), [](std::string& data) -> std::string
{
// for sql, this is easy, just return the value as is
return data;
}));
};
// func
template<class T>
void bind(std::string& input, const std::string& expr, T data)
{
ReplaceMap::const_iterator cit(typeMap_.find(typeid(T)));
if(cit != typeMap_.end())
boost::replace_all(input, expr, cit->second(boost::lexical_cast<std::string>(data)));
}; // eo bind
}; // eo class bind
如你所见,我们有bind函数
现在我们可以用类型安全的方式绑定了!
binder b;
std::string data = "SELECT * FROM table WHERE _user = :user AND _id = :id";
b.bind(data, ":user", "Moo-Juice");
b.bind(data, ":id", 32);
相关文章:
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 在基于范围的for循环中使用结构化绑定声明
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- ODBC:如何将空字符串绑定到C 中的空
- 尝试将字符串传递到绑定的函数C
- Node-ffi 绑定到 NULL 终止的 C 字符串数组,但得到“分段错误:11”
- 字符串文字绑定到一个非常量字符指针
- 将char*绑定到字符串
- 如何函数<void(字符串消息)>绑定到成员函数?
- Sample.exe中0x7537812f处未处理的异常:0xC0020001:字符串绑定无效
- Clang:将绑定或mem_fn与字符串::c_str和转换一起使用时出现问题
- 代码合成XSD解析/数据绑定xml字符串,而不是xml文件
- 使用带有绑定的boost字符串算法谓词
- 增强绑定和分配以将矢量转换为字符串
- 在c++中使用递归解除字符串的绑定
- C++如何创建"绑定"字符串文本替换方法?
- 绑定密钥?(c)(将字符串转换为函数)
- 将C++_TCHAR绑定到SWIG接口中的C#字符串
- 如何在绑定中使字符串类C++"own"自动转换为python字符串