Vreau să fac ceva fancy, îmi place mult ideea de a folosi prepared statements, dar vreau să ascund complexitatea operaţiei sub o funcţie de tip printtf (dar typesafe), ceva de genul:
ICESQLDatabase db;
db.exec("UPDATE articole (denumire, cantitate, pret) VALUES (?, ?, ?) WHERE id = ?", "Pix", 2, 6.5, 521);
M-am gândit la o implementare de genul (probabil chiar funcţionează), dar mi se pare cam verbose:
class ICESQLDatabase {
public:
struct Blob {
Blob() : ptr(nullptr), len(0) {}
Blob(const void *ptr, int len) : ptr(ptr), len(len) {}
const void *ptr;
int len;
};
public:
ICESQLDatabase();
~ICESQLDatabase();
void exec(const ICEString &sql)
{
debug("%s", sql.text());
}
template<typename ... Args> void exec(const ICEString &sql, Args ... args)
{
debug("%s", sql.text());
getBinds(args...);
}
private:
void getBinds(nullptr_t)
{
debug("NULL");
}
template<typename ... Args> void getBinds(nullptr_t, Args ... args)
{
debug("NULL");
getBinds(args...);
}
void getBinds(int val)
{
debug("%d", val);
}
template<typename ... Args> void getBinds(int val, Args ... args)
{
debug("%d", val);
getBinds(args...);
}
void getBinds(double val)
{
debug("%0.2f", val);
}
template<typename ... Args> void getBinds(double val, Args ... args)
{
debug("%0.2f", val);
getBinds(args...);
}
void getBinds(const ICEString &val)
{
debug("%s", val.text());
}
template<typename ... Args> void getBinds(const ICEString &val, Args ... args)
{
debug("%s", val.text());
getBinds(args...);
}
void getBinds(const Blob &data)
{
debug("%p %d", data.ptr, data.len);
}
template<typename ... Args> void getBinds(const Blob &data, Args ... args)
{
debug("%p %d", data.ptr, data.len);
getBinds(args...);
}
};
Ceva idei de optimizare?